From 426e409778cf4b5116a42e7fe8015c3f7cd6d183 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Dec 2025 01:51:07 +0000 Subject: [PATCH] chore(deps): bump the k8s group across 1 directory with 2 updates Bumps the k8s group with 2 updates in the / directory: [k8s.io/kubernetes](https://github.com/kubernetes/kubernetes) and [k8s.io/mount-utils](https://github.com/kubernetes/mount-utils). Updates `k8s.io/kubernetes` from 1.33.7 to 1.34.3 - [Release notes](https://github.com/kubernetes/kubernetes/releases) - [Commits](https://github.com/kubernetes/kubernetes/compare/v1.33.7...v1.34.3) Updates `k8s.io/mount-utils` from 0.34.2 to 0.34.3 - [Commits](https://github.com/kubernetes/mount-utils/compare/v0.34.2...v0.34.3) --- updated-dependencies: - dependency-name: k8s.io/kubernetes dependency-version: 1.34.3 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: k8s - dependency-name: k8s.io/mount-utils dependency-version: 0.34.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: k8s ... Signed-off-by: dependabot[bot] --- go.mod | 63 +- go.sum | 132 +- vendor/cel.dev/expr/.bazelversion | 2 +- vendor/cel.dev/expr/MODULE.bazel | 34 +- vendor/cel.dev/expr/README.md | 2 - vendor/cel.dev/expr/cloudbuild.yaml | 2 +- vendor/cel.dev/expr/eval.pb.go | 361 +- vendor/github.com/JeffAshton/win_pdh/AUTHORS | 14 - vendor/github.com/JeffAshton/win_pdh/LICENSE | 23 - .../JeffAshton/win_pdh/README.mdown | 15 - vendor/github.com/JeffAshton/win_pdh/pdh.go | 453 - .../Microsoft/go-winio/.gitattributes | 1 - .../github.com/Microsoft/go-winio/.gitignore | 10 - .../Microsoft/go-winio/.golangci.yml | 147 - .../github.com/Microsoft/go-winio/CODEOWNERS | 1 - vendor/github.com/Microsoft/go-winio/LICENSE | 22 - .../github.com/Microsoft/go-winio/README.md | 89 - .../github.com/Microsoft/go-winio/SECURITY.md | 41 - .../github.com/Microsoft/go-winio/backup.go | 287 - vendor/github.com/Microsoft/go-winio/doc.go | 22 - vendor/github.com/Microsoft/go-winio/ea.go | 137 - vendor/github.com/Microsoft/go-winio/file.go | 320 - .../github.com/Microsoft/go-winio/fileinfo.go | 106 - .../github.com/Microsoft/go-winio/hvsock.go | 582 - .../Microsoft/go-winio/internal/fs/doc.go | 2 - .../Microsoft/go-winio/internal/fs/fs.go | 262 - .../go-winio/internal/fs/security.go | 12 - .../go-winio/internal/fs/zsyscall_windows.go | 61 - .../go-winio/internal/socket/rawaddr.go | 20 - .../go-winio/internal/socket/socket.go | 177 - .../internal/socket/zsyscall_windows.go | 69 - .../go-winio/internal/stringbuffer/wstring.go | 132 - vendor/github.com/Microsoft/go-winio/pipe.go | 586 - .../Microsoft/go-winio/pkg/guid/guid.go | 232 - .../go-winio/pkg/guid/guid_nonwindows.go | 16 - .../go-winio/pkg/guid/guid_windows.go | 13 - .../go-winio/pkg/guid/variant_string.go | 27 - .../Microsoft/go-winio/privilege.go | 196 - .../github.com/Microsoft/go-winio/reparse.go | 131 - vendor/github.com/Microsoft/go-winio/sd.go | 133 - .../github.com/Microsoft/go-winio/syscall.go | 5 - .../Microsoft/go-winio/zsyscall_windows.go | 378 - .../containerd/containerd/api/LICENSE | 191 - .../services/containers/v1/containers.pb.go | 1178 - .../services/containers/v1/containers.proto | 181 - .../containers/v1/containers_grpc.pb.go | 316 - .../containers/v1/containers_ttrpc.pb.go | 174 - .../api/services/containers/v1/doc.go | 17 - .../containerd/api/services/tasks/v1/doc.go | 17 - .../api/services/tasks/v1/tasks.pb.go | 2359 - .../api/services/tasks/v1/tasks.proto | 227 - .../api/services/tasks/v1/tasks_grpc.pb.go | 692 - .../api/services/tasks/v1/tasks_ttrpc.pb.go | 301 - .../containerd/api/services/version/v1/doc.go | 18 - .../api/services/version/v1/version.pb.go | 187 - .../api/services/version/v1/version.proto | 33 - .../services/version/v1/version_grpc.pb.go | 108 - .../services/version/v1/version_ttrpc.pb.go | 45 - .../containerd/api/types/descriptor.pb.go | 206 - .../containerd/api/types/descriptor.proto | 33 - .../containerd/containerd/api/types/doc.go | 17 - .../containerd/api/types/event.pb.go | 209 - .../containerd/api/types/event.proto | 33 - .../containerd/api/types/fieldpath.pb.go | 144 - .../containerd/api/types/fieldpath.proto | 42 - .../containerd/api/types/introspection.pb.go | 375 - .../containerd/api/types/introspection.proto | 46 - .../containerd/api/types/metrics.pb.go | 194 - .../containerd/api/types/metrics.proto | 30 - .../containerd/api/types/mount.pb.go | 202 - .../containerd/api/types/mount.proto | 43 - .../containerd/api/types/platform.pb.go | 194 - .../containerd/api/types/platform.proto | 30 - .../containerd/api/types/platform_helpers.go | 49 - .../containerd/api/types/sandbox.pb.go | 357 - .../containerd/api/types/sandbox.proto | 54 - .../containerd/api/types/task/doc.go | 18 - .../containerd/api/types/task/task.pb.go | 406 - .../containerd/api/types/task/task.proto | 55 - vendor/github.com/containerd/errdefs/LICENSE | 191 - .../github.com/containerd/errdefs/README.md | 13 - .../github.com/containerd/errdefs/errors.go | 443 - .../github.com/containerd/errdefs/pkg/LICENSE | 191 - .../containerd/errdefs/pkg/errgrpc/grpc.go | 353 - .../errdefs/pkg/internal/cause/cause.go | 33 - .../errdefs/pkg/internal/types/collapsible.go | 57 - .../github.com/containerd/errdefs/resolve.go | 147 - .../github.com/containerd/log/.golangci.yml | 30 - vendor/github.com/containerd/log/LICENSE | 191 - vendor/github.com/containerd/log/README.md | 17 - vendor/github.com/containerd/log/context.go | 182 - .../containerd/ttrpc/.gitattributes | 1 - vendor/github.com/containerd/ttrpc/.gitignore | 13 - .../github.com/containerd/ttrpc/.golangci.yml | 52 - vendor/github.com/containerd/ttrpc/LICENSE | 201 - vendor/github.com/containerd/ttrpc/Makefile | 180 - .../github.com/containerd/ttrpc/PROTOCOL.md | 240 - .../containerd/ttrpc/Protobuild.toml | 28 - vendor/github.com/containerd/ttrpc/README.md | 59 - vendor/github.com/containerd/ttrpc/channel.go | 182 - vendor/github.com/containerd/ttrpc/client.go | 570 - vendor/github.com/containerd/ttrpc/codec.go | 43 - vendor/github.com/containerd/ttrpc/config.go | 86 - vendor/github.com/containerd/ttrpc/doc.go | 23 - vendor/github.com/containerd/ttrpc/errors.go | 80 - .../github.com/containerd/ttrpc/handshake.go | 50 - .../containerd/ttrpc/interceptor.go | 65 - .../github.com/containerd/ttrpc/metadata.go | 107 - .../github.com/containerd/ttrpc/request.pb.go | 396 - .../github.com/containerd/ttrpc/request.proto | 29 - vendor/github.com/containerd/ttrpc/server.go | 579 - .../github.com/containerd/ttrpc/services.go | 279 - vendor/github.com/containerd/ttrpc/stream.go | 84 - .../containerd/ttrpc/stream_server.go | 22 - vendor/github.com/containerd/ttrpc/test.proto | 16 - .../containerd/ttrpc/unixcreds_linux.go | 105 - .../containerd/typeurl/v2/.gitignore | 2 - .../github.com/containerd/typeurl/v2/LICENSE | 191 - .../containerd/typeurl/v2/README.md | 26 - .../github.com/containerd/typeurl/v2/doc.go | 83 - .../github.com/containerd/typeurl/v2/types.go | 307 - .../containerd/typeurl/v2/types_gogo.go | 68 - .../github.com/coreos/go-systemd/v22/LICENSE | 191 - .../github.com/coreos/go-systemd/v22/NOTICE | 5 - .../coreos/go-systemd/v22/dbus/dbus.go | 266 - .../coreos/go-systemd/v22/dbus/methods.go | 864 - .../coreos/go-systemd/v22/dbus/properties.go | 237 - .../coreos/go-systemd/v22/dbus/set.go | 47 - .../go-systemd/v22/dbus/subscription.go | 333 - .../go-systemd/v22/dbus/subscription_set.go | 57 - .../cyphar/filepath-securejoin/.golangci.yml | 60 - .../cyphar/filepath-securejoin/CHANGELOG.md | 461 - .../cyphar/filepath-securejoin/README.md | 184 - .../cyphar/filepath-securejoin/VERSION | 1 - .../cyphar/filepath-securejoin/codecov.yml | 29 - .../cyphar/filepath-securejoin/doc.go | 47 - .../cyphar/filepath-securejoin/join.go | 169 - .../cyphar/filepath-securejoin/vfs.go | 37 - .../docker/go-units/CONTRIBUTING.md | 67 - vendor/github.com/docker/go-units/LICENSE | 191 - vendor/github.com/docker/go-units/MAINTAINERS | 46 - vendor/github.com/docker/go-units/README.md | 16 - vendor/github.com/docker/go-units/circle.yml | 11 - vendor/github.com/docker/go-units/duration.go | 35 - vendor/github.com/docker/go-units/size.go | 154 - vendor/github.com/docker/go-units/ulimit.go | 123 - .../emicklei/go-restful/v3/CHANGES.md | 5 +- .../emicklei/go-restful/v3/README.md | 2 +- .../emicklei/go-restful/v3/jsr311.go | 19 +- .../emicklei/go-restful/v3/route.go | 2 + .../go-kmsg-parser/kmsgparser/kmsgparser.go | 200 - .../euank/go-kmsg-parser/kmsgparser/log.go | 55 - vendor/github.com/fxamacker/cbor/v2/README.md | 607 +- .../fxamacker/cbor/v2/bytestring.go | 27 + vendor/github.com/fxamacker/cbor/v2/cache.go | 25 +- vendor/github.com/fxamacker/cbor/v2/common.go | 9 + vendor/github.com/fxamacker/cbor/v2/decode.go | 425 +- vendor/github.com/fxamacker/cbor/v2/doc.go | 51 +- vendor/github.com/fxamacker/cbor/v2/encode.go | 442 +- .../fxamacker/cbor/v2/encode_map.go | 10 +- .../fxamacker/cbor/v2/encode_map_go117.go | 60 - .../fxamacker/cbor/v2/omitzero_go124.go | 8 + .../fxamacker/cbor/v2/omitzero_pre_go124.go | 8 + .../fxamacker/cbor/v2/simplevalue.go | 29 + vendor/github.com/fxamacker/cbor/v2/stream.go | 4 +- .../fxamacker/cbor/v2/structfields.go | 18 +- vendor/github.com/fxamacker/cbor/v2/tag.go | 48 +- .../github.com/godbus/dbus/v5/CONTRIBUTING.md | 50 - vendor/github.com/godbus/dbus/v5/LICENSE | 25 - vendor/github.com/godbus/dbus/v5/MAINTAINERS | 3 - vendor/github.com/godbus/dbus/v5/README.md | 46 - vendor/github.com/godbus/dbus/v5/auth.go | 257 - .../godbus/dbus/v5/auth_anonymous.go | 16 - .../godbus/dbus/v5/auth_external.go | 26 - vendor/github.com/godbus/dbus/v5/auth_sha1.go | 102 - vendor/github.com/godbus/dbus/v5/call.go | 69 - vendor/github.com/godbus/dbus/v5/conn.go | 996 - .../github.com/godbus/dbus/v5/conn_darwin.go | 37 - .../github.com/godbus/dbus/v5/conn_other.go | 90 - vendor/github.com/godbus/dbus/v5/conn_unix.go | 17 - .../github.com/godbus/dbus/v5/conn_windows.go | 15 - vendor/github.com/godbus/dbus/v5/dbus.go | 430 - vendor/github.com/godbus/dbus/v5/decoder.go | 292 - .../godbus/dbus/v5/default_handler.go | 342 - vendor/github.com/godbus/dbus/v5/doc.go | 71 - vendor/github.com/godbus/dbus/v5/encoder.go | 235 - vendor/github.com/godbus/dbus/v5/escape.go | 84 - vendor/github.com/godbus/dbus/v5/export.go | 463 - vendor/github.com/godbus/dbus/v5/homedir.go | 25 - vendor/github.com/godbus/dbus/v5/match.go | 89 - vendor/github.com/godbus/dbus/v5/message.go | 390 - vendor/github.com/godbus/dbus/v5/object.go | 174 - vendor/github.com/godbus/dbus/v5/sequence.go | 24 - .../godbus/dbus/v5/sequential_handler.go | 125 - .../godbus/dbus/v5/server_interfaces.go | 107 - vendor/github.com/godbus/dbus/v5/sig.go | 293 - .../godbus/dbus/v5/transport_darwin.go | 6 - .../godbus/dbus/v5/transport_generic.go | 52 - .../godbus/dbus/v5/transport_nonce_tcp.go | 39 - .../godbus/dbus/v5/transport_tcp.go | 41 - .../godbus/dbus/v5/transport_unix.go | 212 - .../dbus/v5/transport_unixcred_dragonfly.go | 95 - .../dbus/v5/transport_unixcred_freebsd.go | 92 - .../dbus/v5/transport_unixcred_linux.go | 25 - .../dbus/v5/transport_unixcred_netbsd.go | 14 - .../dbus/v5/transport_unixcred_openbsd.go | 14 - .../godbus/dbus/v5/transport_zos.go | 6 - vendor/github.com/godbus/dbus/v5/variant.go | 150 - .../godbus/dbus/v5/variant_lexer.go | 284 - .../godbus/dbus/v5/variant_parser.go | 817 - .../gogo/protobuf/gogoproto/Makefile | 37 - .../github.com/gogo/protobuf/gogoproto/doc.go | 169 - .../gogo/protobuf/gogoproto/gogo.pb.go | 874 - .../gogo/protobuf/gogoproto/gogo.pb.golden | 45 - .../gogo/protobuf/gogoproto/gogo.proto | 144 - .../gogo/protobuf/gogoproto/helper.go | 415 - .../protoc-gen-gogo/descriptor/Makefile | 36 - .../protoc-gen-gogo/descriptor/descriptor.go | 118 - .../descriptor/descriptor.pb.go | 2865 - .../descriptor/descriptor_gostring.gen.go | 752 - .../protoc-gen-gogo/descriptor/helper.go | 390 - vendor/github.com/google/cadvisor/AUTHORS | 9 - vendor/github.com/google/cadvisor/LICENSE | 190 - .../google/cadvisor/cache/memory/memory.go | 142 - .../cadvisor/collector/collector_manager.go | 109 - .../google/cadvisor/collector/config.go | 101 - .../google/cadvisor/collector/fakes.go | 37 - .../cadvisor/collector/generic_collector.go | 183 - .../collector/prometheus_collector.go | 286 - .../google/cadvisor/collector/types.go | 53 - .../google/cadvisor/collector/util.go | 26 - .../container/common/container_hints.go | 60 - .../cadvisor/container/common/fsHandler.go | 155 - .../cadvisor/container/common/helpers.go | 459 - .../container/common/inotify_watcher.go | 135 - .../google/cadvisor/container/container.go | 79 - .../cadvisor/container/containerd/client.go | 162 - .../containerd/containers/containers.go | 125 - .../cadvisor/container/containerd/factory.go | 157 - .../cadvisor/container/containerd/grpc.go | 49 - .../cadvisor/container/containerd/handler.go | 250 - .../containerd/identifiers/validate.go | 86 - .../container/containerd/install/install.go | 30 - .../containerd/namespaces/context.go | 92 - .../container/containerd/namespaces/grpc.go | 74 - .../container/containerd/namespaces/store.go | 57 - .../container/containerd/namespaces/ttrpc.go | 64 - .../container/containerd/pkg/dialer/dialer.go | 92 - .../containerd/pkg/dialer/dialer_unix.go | 66 - .../containerd/pkg/dialer/dialer_windows.go | 51 - .../cadvisor/container/containerd/plugin.go | 38 - .../google/cadvisor/container/crio/client.go | 167 - .../google/cadvisor/container/crio/factory.go | 166 - .../google/cadvisor/container/crio/handler.go | 362 - .../container/crio/install/install.go | 30 - .../google/cadvisor/container/crio/plugin.go | 51 - .../google/cadvisor/container/factory.go | 332 - .../container/libcontainer/handler.go | 936 - .../container/libcontainer/helpers.go | 167 - .../google/cadvisor/container/raw/factory.go | 114 - .../google/cadvisor/container/raw/handler.go | 304 - .../google/cadvisor/container/raw/watcher.go | 243 - .../cadvisor/container/systemd/factory.go | 59 - .../container/systemd/install/install.go | 30 - .../cadvisor/container/systemd/plugin.go | 38 - .../cadvisor/devicemapper/dmsetup_client.go | 64 - .../google/cadvisor/devicemapper/doc.go | 16 - .../cadvisor/devicemapper/thin_ls_client.go | 93 - .../devicemapper/thin_pool_watcher.go | 179 - .../google/cadvisor/devicemapper/util.go | 50 - .../google/cadvisor/events/handler.go | 339 - vendor/github.com/google/cadvisor/fs/fs.go | 882 - vendor/github.com/google/cadvisor/fs/types.go | 133 - .../google/cadvisor/info/v1/container.go | 1109 - .../google/cadvisor/info/v1/docker.go | 38 - .../google/cadvisor/info/v1/machine.go | 327 - .../google/cadvisor/info/v1/metric.go | 77 - .../google/cadvisor/info/v2/container.go | 358 - .../google/cadvisor/info/v2/conversion.go | 316 - .../google/cadvisor/info/v2/machine.go | 198 - .../google/cadvisor/machine/info.go | 178 - .../google/cadvisor/machine/machine.go | 286 - .../cadvisor/machine/operatingsystem_unix.go | 54 - .../machine/operatingsystem_windows.go | 54 - .../google/cadvisor/manager/container.go | 763 - .../google/cadvisor/manager/manager.go | 1421 - .../google/cadvisor/nvm/machine_libipmctl.go | 138 - .../cadvisor/nvm/machine_no_libipmctl.go | 36 - .../google/cadvisor/perf/collector_libpfm.go | 456 - .../cadvisor/perf/collector_no_libpfm.go | 34 - .../github.com/google/cadvisor/perf/config.go | 127 - .../google/cadvisor/perf/manager_libpfm.go | 75 - .../google/cadvisor/perf/manager_no_libpfm.go | 31 - .../google/cadvisor/perf/types_libpfm.go | 54 - .../google/cadvisor/perf/uncore_libpfm.go | 519 - .../google/cadvisor/resctrl/factory.go | 58 - .../github.com/google/cadvisor/stats/noop.go | 44 - .../github.com/google/cadvisor/stats/types.go | 35 - .../google/cadvisor/storage/common_flags.go | 28 - .../google/cadvisor/storage/storage.go | 59 - .../google/cadvisor/summary/buffer.go | 74 - .../google/cadvisor/summary/percentiles.go | 201 - .../google/cadvisor/summary/summary.go | 184 - .../cadvisor/utils/cloudinfo/cloudinfo.go | 89 - .../google/cadvisor/utils/cpuload/cpuload.go | 47 - .../cadvisor/utils/cpuload/netlink/conn.go | 98 - .../cadvisor/utils/cpuload/netlink/netlink.go | 241 - .../cadvisor/utils/cpuload/netlink/reader.go | 80 - .../cadvisor/utils/oomparser/oomparser.go | 174 - .../github.com/google/cadvisor/utils/path.go | 24 - .../google/cadvisor/utils/sysfs/sysfs.go | 603 - .../cadvisor/utils/sysfs/sysfs_notx86.go | 20 - .../google/cadvisor/utils/sysfs/sysfs_x86.go | 20 - .../google/cadvisor/utils/sysinfo/sysinfo.go | 614 - .../google/cadvisor/utils/timed_store.go | 164 - .../github.com/google/cadvisor/utils/utils.go | 29 - .../google/cadvisor/version/version.go | 35 - .../google/cadvisor/watcher/watcher.go | 51 - .../github.com/google/cel-go/cel/BUILD.bazel | 13 +- vendor/github.com/google/cel-go/cel/decls.go | 70 +- vendor/github.com/google/cel-go/cel/env.go | 233 +- .../github.com/google/cel-go/cel/folding.go | 60 +- vendor/github.com/google/cel-go/cel/io.go | 57 +- .../github.com/google/cel-go/cel/library.go | 409 +- vendor/github.com/google/cel-go/cel/macro.go | 30 +- .../github.com/google/cel-go/cel/options.go | 227 +- .../github.com/google/cel-go/cel/program.go | 274 +- vendor/github.com/google/cel-go/cel/prompt.go | 155 + .../cel-go/cel/templates/authoring.tmpl | 56 + .../github.com/google/cel-go/cel/validator.go | 70 +- .../google/cel-go/checker/checker.go | 11 + .../github.com/google/cel-go/checker/cost.go | 7 +- .../google/cel-go/checker/decls/decls.go | 37 +- .../google/cel-go/checker/errors.go | 4 + .../google/cel-go/common/BUILD.bazel | 2 + .../google/cel-go/common/ast/ast.go | 78 + .../google/cel-go/common/ast/navigable.go | 7 +- .../cel-go/common/containers/container.go | 14 +- .../google/cel-go/common/decls/BUILD.bazel | 2 + .../google/cel-go/common/decls/decls.go | 287 +- vendor/github.com/google/cel-go/common/doc.go | 154 + .../google/cel-go/common/env/BUILD.bazel | 50 + .../google/cel-go/common/env/env.go | 887 + .../google/cel-go/common/stdlib/BUILD.bazel | 1 + .../google/cel-go/common/stdlib/standard.go | 702 +- .../google/cel-go/common/types/BUILD.bazel | 1 + .../google/cel-go/common/types/bool.go | 9 + .../google/cel-go/common/types/bytes.go | 15 + .../google/cel-go/common/types/double.go | 22 + .../google/cel-go/common/types/duration.go | 5 + .../google/cel-go/common/types/format.go | 42 + .../google/cel-go/common/types/int.go | 5 + .../google/cel-go/common/types/list.go | 16 + .../google/cel-go/common/types/map.go | 36 + .../google/cel-go/common/types/null.go | 5 + .../google/cel-go/common/types/object.go | 29 + .../google/cel-go/common/types/optional.go | 11 + .../google/cel-go/common/types/string.go | 4 + .../google/cel-go/common/types/timestamp.go | 4 + .../google/cel-go/common/types/types.go | 11 +- .../google/cel-go/common/types/uint.go | 6 + .../github.com/google/cel-go/ext/BUILD.bazel | 17 +- vendor/github.com/google/cel-go/ext/README.md | 30 +- .../github.com/google/cel-go/ext/bindings.go | 10 +- .../cel-go/ext/extension_option_factory.go | 75 + .../google/cel-go/ext/formatting.go | 25 +- .../google/cel-go/ext/formatting_v2.go | 788 + vendor/github.com/google/cel-go/ext/lists.go | 268 +- vendor/github.com/google/cel-go/ext/math.go | 47 + vendor/github.com/google/cel-go/ext/native.go | 2 +- vendor/github.com/google/cel-go/ext/regex.go | 332 + vendor/github.com/google/cel-go/ext/sets.go | 14 +- .../github.com/google/cel-go/ext/strings.go | 63 +- .../google/cel-go/interpreter/activation.go | 14 +- .../cel-go/interpreter/attribute_patterns.go | 2 +- .../cel-go/interpreter/interpretable.go | 86 +- .../google/cel-go/interpreter/interpreter.go | 188 +- .../google/cel-go/interpreter/planner.go | 48 +- .../google/cel-go/interpreter/runtimecost.go | 225 +- .../github.com/google/cel-go/parser/macro.go | 181 +- .../google/gnostic-models/compiler/context.go | 2 +- .../gnostic-models/compiler/extensions.go | 2 +- .../google/gnostic-models/compiler/helpers.go | 2 +- .../google/gnostic-models/compiler/reader.go | 2 +- .../gnostic-models/jsonschema/models.go | 2 +- .../gnostic-models/jsonschema/reader.go | 2 +- .../gnostic-models/jsonschema/writer.go | 2 +- .../gnostic-models/openapiv2/OpenAPIv2.go | 80 +- .../gnostic-models/openapiv2/document.go | 2 +- .../gnostic-models/openapiv3/OpenAPIv3.go | 24 +- .../gnostic-models/openapiv3/document.go | 2 +- .../google/go-cmp/cmp/cmpopts/equate.go | 185 - .../google/go-cmp/cmp/cmpopts/ignore.go | 206 - .../google/go-cmp/cmp/cmpopts/sort.go | 171 - .../go-cmp/cmp/cmpopts/struct_filter.go | 189 - .../google/go-cmp/cmp/cmpopts/xform.go | 36 - .../v2/interceptors/client.go | 25 +- .../grpc-gateway/v2/runtime/errors.go | 32 +- .../grpc-gateway/v2/runtime/handler.go | 12 +- .../grpc-gateway/v2/runtime/mux.go | 8 + .../grpc-gateway/v2/runtime/query.go | 16 +- .../github.com/karrick/godirwalk/.gitignore | 19 - vendor/github.com/karrick/godirwalk/LICENSE | 25 - vendor/github.com/karrick/godirwalk/README.md | 324 - .../karrick/godirwalk/azure-pipelines.yml | 53 - vendor/github.com/karrick/godirwalk/bench.sh | 7 - .../karrick/godirwalk/debug_development.go | 14 - .../karrick/godirwalk/debug_release.go | 6 - vendor/github.com/karrick/godirwalk/dirent.go | 104 - vendor/github.com/karrick/godirwalk/doc.go | 42 - .../karrick/godirwalk/inoWithFileno.go | 9 - .../karrick/godirwalk/inoWithIno.go | 9 - .../github.com/karrick/godirwalk/modeType.go | 22 - .../karrick/godirwalk/modeTypeWithType.go | 37 - .../karrick/godirwalk/modeTypeWithoutType.go | 18 - .../karrick/godirwalk/nameWithNamlen.go | 29 - .../karrick/godirwalk/nameWithoutNamlen.go | 42 - .../github.com/karrick/godirwalk/readdir.go | 53 - .../karrick/godirwalk/readdir_unix.go | 131 - .../karrick/godirwalk/readdir_windows.go | 66 - .../karrick/godirwalk/reclenFromNamlen.go | 9 - .../karrick/godirwalk/reclenFromReclen.go | 9 - .../karrick/godirwalk/scandir_unix.go | 181 - .../karrick/godirwalk/scandir_windows.go | 149 - .../github.com/karrick/godirwalk/scanner.go | 44 - vendor/github.com/karrick/godirwalk/walk.go | 379 - vendor/github.com/mistifyio/go-zfs/.gitignore | 1 - .../github.com/mistifyio/go-zfs/.travis.yml | 43 - .../mistifyio/go-zfs/CONTRIBUTING.md | 60 - vendor/github.com/mistifyio/go-zfs/LICENSE | 201 - vendor/github.com/mistifyio/go-zfs/README.md | 54 - .../github.com/mistifyio/go-zfs/Vagrantfile | 34 - vendor/github.com/mistifyio/go-zfs/error.go | 18 - vendor/github.com/mistifyio/go-zfs/utils.go | 360 - .../mistifyio/go-zfs/utils_notsolaris.go | 17 - .../mistifyio/go-zfs/utils_solaris.go | 17 - vendor/github.com/mistifyio/go-zfs/zfs.go | 452 - vendor/github.com/mistifyio/go-zfs/zpool.go | 112 - vendor/github.com/moby/sys/userns/LICENSE | 202 - vendor/github.com/moby/sys/userns/userns.go | 16 - .../moby/sys/userns/userns_linux.go | 53 - .../moby/sys/userns/userns_linux_fuzzer.go | 8 - .../moby/sys/userns/userns_unsupported.go | 6 - .../modern-go/reflect2/safe_type.go | 22 +- .../opencontainers/cgroups/CODEOWNERS | 1 - .../opencontainers/cgroups/CONTRIBUTING.md | 150 - .../opencontainers/cgroups/GOVERNANCE.md | 63 - .../github.com/opencontainers/cgroups/LICENSE | 201 - .../opencontainers/cgroups/MAINTAINERS | 8 - .../cgroups/MAINTAINERS_GUIDE.md | 92 - .../opencontainers/cgroups/README.md | 11 - .../opencontainers/cgroups/RELEASES.md | 51 - .../opencontainers/cgroups/cgroups.go | 78 - .../cgroups/config_blkio_device.go | 66 - .../cgroups/config_hugepages.go | 9 - .../cgroups/config_ifprio_map.go | 14 - .../opencontainers/cgroups/config_linux.go | 169 - .../opencontainers/cgroups/config_rdma.go | 9 - .../cgroups/config_unsupported.go | 8 - .../cgroups/devices/config/device.go | 174 - .../cgroups/devices/config/mknod_unix.go | 14 - .../github.com/opencontainers/cgroups/file.go | 216 - .../opencontainers/cgroups/fs/blkio.go | 310 - .../opencontainers/cgroups/fs/cpu.go | 181 - .../opencontainers/cgroups/fs/cpuacct.go | 158 - .../opencontainers/cgroups/fs/cpuset.go | 276 - .../opencontainers/cgroups/fs/devices.go | 38 - .../opencontainers/cgroups/fs/error.go | 15 - .../opencontainers/cgroups/fs/freezer.go | 157 - .../opencontainers/cgroups/fs/fs.go | 265 - .../opencontainers/cgroups/fs/hugetlb.go | 83 - .../opencontainers/cgroups/fs/memory.go | 356 - .../opencontainers/cgroups/fs/name.go | 30 - .../opencontainers/cgroups/fs/net_cls.go | 31 - .../opencontainers/cgroups/fs/net_prio.go | 29 - .../opencontainers/cgroups/fs/paths.go | 169 - .../opencontainers/cgroups/fs/perf_event.go | 23 - .../opencontainers/cgroups/fs/pids.go | 61 - .../opencontainers/cgroups/fs/rdma.go | 24 - .../opencontainers/cgroups/fs2/cpu.go | 117 - .../opencontainers/cgroups/fs2/cpuset.go | 27 - .../opencontainers/cgroups/fs2/create.go | 151 - .../opencontainers/cgroups/fs2/defaultpath.go | 80 - .../opencontainers/cgroups/fs2/freezer.go | 124 - .../opencontainers/cgroups/fs2/fs2.go | 316 - .../opencontainers/cgroups/fs2/hugetlb.go | 69 - .../opencontainers/cgroups/fs2/io.go | 192 - .../opencontainers/cgroups/fs2/memory.go | 241 - .../opencontainers/cgroups/fs2/misc.go | 52 - .../opencontainers/cgroups/fs2/pids.go | 71 - .../opencontainers/cgroups/fs2/psi.go | 89 - .../opencontainers/cgroups/fscommon/rdma.go | 120 - .../opencontainers/cgroups/fscommon/utils.go | 144 - .../opencontainers/cgroups/getallpids.go | 27 - .../cgroups/internal/path/path.go | 52 - .../opencontainers/cgroups/manager/new.go | 77 - .../opencontainers/cgroups/stats.go | 200 - .../opencontainers/cgroups/systemd/common.go | 362 - .../opencontainers/cgroups/systemd/cpuset.go | 60 - .../opencontainers/cgroups/systemd/dbus.go | 102 - .../opencontainers/cgroups/systemd/devices.go | 74 - .../opencontainers/cgroups/systemd/user.go | 92 - .../opencontainers/cgroups/systemd/v1.go | 412 - .../opencontainers/cgroups/systemd/v2.go | 515 - .../opencontainers/cgroups/utils.go | 468 - .../opencontainers/cgroups/v1_utils.go | 277 - .../opencontainers/image-spec/LICENSE | 191 - .../image-spec/specs-go/v1/annotations.go | 62 - .../image-spec/specs-go/v1/config.go | 111 - .../image-spec/specs-go/v1/descriptor.go | 80 - .../image-spec/specs-go/v1/index.go | 38 - .../image-spec/specs-go/v1/layout.go | 32 - .../image-spec/specs-go/v1/manifest.go | 41 - .../image-spec/specs-go/v1/mediatype.go | 85 - .../image-spec/specs-go/version.go | 32 - .../image-spec/specs-go/versioned.go | 23 - .../opencontainers/runtime-spec/LICENSE | 191 - .../runtime-spec/specs-go/config.go | 889 - .../runtime-spec/specs-go/state.go | 56 - .../runtime-spec/specs-go/version.go | 18 - vendor/github.com/sirupsen/logrus/.gitignore | 4 - .../github.com/sirupsen/logrus/.golangci.yml | 40 - vendor/github.com/sirupsen/logrus/.travis.yml | 15 - .../github.com/sirupsen/logrus/CHANGELOG.md | 259 - vendor/github.com/sirupsen/logrus/LICENSE | 21 - vendor/github.com/sirupsen/logrus/README.md | 515 - vendor/github.com/sirupsen/logrus/alt_exit.go | 76 - .../github.com/sirupsen/logrus/appveyor.yml | 14 - .../github.com/sirupsen/logrus/buffer_pool.go | 43 - vendor/github.com/sirupsen/logrus/doc.go | 26 - vendor/github.com/sirupsen/logrus/entry.go | 442 - vendor/github.com/sirupsen/logrus/exported.go | 270 - .../github.com/sirupsen/logrus/formatter.go | 78 - vendor/github.com/sirupsen/logrus/hooks.go | 34 - .../sirupsen/logrus/json_formatter.go | 128 - vendor/github.com/sirupsen/logrus/logger.go | 417 - vendor/github.com/sirupsen/logrus/logrus.go | 186 - .../logrus/terminal_check_appengine.go | 11 - .../sirupsen/logrus/terminal_check_bsd.go | 13 - .../sirupsen/logrus/terminal_check_js.go | 7 - .../logrus/terminal_check_no_terminal.go | 11 - .../logrus/terminal_check_notappengine.go | 17 - .../sirupsen/logrus/terminal_check_solaris.go | 11 - .../sirupsen/logrus/terminal_check_unix.go | 13 - .../sirupsen/logrus/terminal_check_windows.go | 27 - .../sirupsen/logrus/text_formatter.go | 339 - vendor/github.com/sirupsen/logrus/writer.go | 102 - .../google.golang.org/grpc/otelgrpc/LICENSE | 201 - .../google.golang.org/grpc/otelgrpc/config.go | 305 - .../google.golang.org/grpc/otelgrpc/doc.go | 11 - .../grpc/otelgrpc/interceptor.go | 530 - .../grpc/otelgrpc/interceptorinfo.go | 39 - .../grpc/otelgrpc/internal/parse.go | 40 - .../grpc/otelgrpc/metadata_supplier.go | 87 - .../grpc/otelgrpc/semconv.go | 41 - .../grpc/otelgrpc/stats_handler.go | 223 - .../grpc/otelgrpc/version.go | 17 - .../otlp/otlptrace/otlptracegrpc/client.go | 2 +- .../otel/exporters/otlp/otlptrace/version.go | 2 +- .../proto/otlp/trace/v1/trace.pb.go | 6 +- .../rpc/errdetails/error_details.pb.go | 128 +- .../grpc/balancer/balancer.go | 115 +- .../grpc/balancer/base/balancer.go | 12 +- .../endpointsharding/endpointsharding.go | 356 + .../balancer/pickfirst/internal/internal.go | 17 +- .../grpc/balancer/pickfirst/pickfirst.go | 2 +- .../pickfirst/pickfirstleaf/pickfirstleaf.go | 518 +- .../grpc/balancer/roundrobin/roundrobin.go | 70 +- .../grpc/balancer/subconn.go | 134 + .../grpc/balancer_wrapper.go | 151 +- .../grpc_binarylog_v1/binarylog.pb.go | 296 +- vendor/google.golang.org/grpc/clientconn.go | 61 +- vendor/google.golang.org/grpc/codec.go | 2 +- .../google.golang.org/grpc/credentials/tls.go | 6 +- vendor/google.golang.org/grpc/dialoptions.go | 55 +- .../grpc/experimental/stats/metricregistry.go | 27 +- .../grpc/experimental/stats/metrics.go | 78 +- .../grpc/grpclog/internal/loggerv2.go | 107 +- .../grpc/health/grpc_health_v1/health.pb.go | 238 +- .../health/grpc_health_v1/health_grpc.pb.go | 64 +- .../grpc/internal/backoff/backoff.go | 2 +- .../balancer/gracefulswitch/gracefulswitch.go | 10 +- .../grpc/internal/envconfig/envconfig.go | 22 +- .../grpc/internal/envconfig/xds.go | 10 + .../grpc/internal/grpcsync/oncefunc.go | 32 - .../grpc/internal/internal.go | 62 +- .../grpc/internal/metadata/metadata.go | 26 +- .../proxyattributes/proxyattributes.go | 54 + .../delegatingresolver/delegatingresolver.go | 412 + .../internal/resolver/dns/dns_resolver.go | 41 +- .../grpc/internal/transport/client_stream.go | 144 + .../grpc/internal/transport/flowcontrol.go | 9 +- .../grpc/internal/transport/handler_server.go | 38 +- .../grpc/internal/transport/http2_client.go | 108 +- .../grpc/internal/transport/http2_server.go | 96 +- .../grpc/internal/transport/http_util.go | 4 +- .../grpc/internal/transport/proxy.go | 62 +- .../grpc/internal/transport/server_stream.go | 180 + .../grpc/internal/transport/transport.go | 323 +- .../grpc/mem/buffer_slice.go | 59 +- .../google.golang.org/grpc/picker_wrapper.go | 2 +- vendor/google.golang.org/grpc/preloader.go | 4 +- .../grpc_reflection_v1/reflection.pb.go | 328 +- .../grpc_reflection_v1alpha/reflection.pb.go | 324 +- vendor/google.golang.org/grpc/resolver/map.go | 174 +- .../grpc/resolver/resolver.go | 25 +- .../grpc/resolver_wrapper.go | 36 +- vendor/google.golang.org/grpc/rpc_util.go | 119 +- vendor/google.golang.org/grpc/server.go | 118 +- .../google.golang.org/grpc/service_config.go | 22 +- .../google.golang.org/grpc/stats/metrics.go | 81 + vendor/google.golang.org/grpc/stats/stats.go | 109 +- vendor/google.golang.org/grpc/stream.go | 348 +- vendor/google.golang.org/grpc/version.go | 2 +- .../apiserver/pkg/endpoints/metrics/OWNERS | 6 - .../pkg/endpoints/metrics/metrics.go | 957 - .../pkg/endpoints/responsewriter/fake.go | 54 - .../pkg/endpoints/responsewriter/wrapper.go | 180 - .../apiserver/pkg/server/healthz/doc.go | 22 - .../apiserver/pkg/server/healthz/healthz.go | 333 - .../apiserver/pkg/server/httplog/doc.go | 19 - .../apiserver/pkg/server/httplog/httplog.go | 342 - .../apiserver/pkg/server/routine/routine.go | 91 - vendor/k8s.io/apiserver/pkg/storage/OWNERS | 22 - .../pkg/storage/api_object_versioner.go | 130 - .../k8s.io/apiserver/pkg/storage/continue.go | 120 - vendor/k8s.io/apiserver/pkg/storage/doc.go | 18 - vendor/k8s.io/apiserver/pkg/storage/errors.go | 250 - .../apiserver/pkg/storage/interfaces.go | 372 - .../pkg/storage/selection_predicate.go | 187 - vendor/k8s.io/apiserver/pkg/storage/util.go | 108 - .../dynamic/dynamicinformer/informer.go | 200 - .../dynamic/dynamicinformer/interface.go | 53 - .../dynamic/dynamiclister/interface.go | 40 - .../client-go/dynamic/dynamiclister/lister.go | 91 - .../client-go/dynamic/dynamiclister/shim.go | 87 - vendor/k8s.io/client-go/tools/events/OWNERS | 10 - vendor/k8s.io/client-go/tools/events/doc.go | 19 - .../tools/events/event_broadcaster.go | 457 - .../client-go/tools/events/event_recorder.go | 113 - vendor/k8s.io/client-go/tools/events/fake.go | 52 - .../k8s.io/client-go/tools/events/helper.go | 64 - .../client-go/tools/events/interfaces.go | 92 - .../k8s.io/cloud-provider/volume/constants.go | 26 - .../cloud-provider/volume/helpers/rounding.go | 165 - .../cloud-provider/volume/helpers/zones.go | 313 - vendor/k8s.io/component-base/config/OWNERS | 13 - vendor/k8s.io/component-base/config/doc.go | 19 - vendor/k8s.io/component-base/config/types.go | 80 - .../config/v1alpha1/conversion.go | 53 - .../config/v1alpha1/defaults.go | 98 - .../component-base/config/v1alpha1/doc.go | 20 - .../config/v1alpha1/register.go | 31 - .../component-base/config/v1alpha1/types.go | 82 - .../v1alpha1/zz_generated.conversion.go | 133 - .../config/v1alpha1/zz_generated.deepcopy.go | 88 - .../config/validation/validation.go | 61 - .../config/zz_generated.deepcopy.go | 73 - .../logs/logreduction/logreduction.go | 78 - .../metrics/prometheus/slis/metrics.go | 75 - .../metrics/prometheus/slis/registry.go | 27 - .../metrics/prometheus/slis/routes.go | 53 - .../node/topology/helpers.go | 58 - .../storage/ephemeral/ephemeral.go | 57 - .../storage/volume/helpers.go | 84 - .../storage/volume/pv_helpers.go | 363 - vendor/k8s.io/cri-api/LICENSE | 201 - .../cri-api/pkg/apis/runtime/v1/api.pb.go | 51395 ---------------- .../cri-api/pkg/apis/runtime/v1/api.proto | 2128 - .../cri-api/pkg/apis/runtime/v1/constants.go | 55 - vendor/k8s.io/cri-api/pkg/apis/services.go | 142 - vendor/k8s.io/cri-client/LICENSE | 201 - vendor/k8s.io/cri-client/pkg/doc.go | 19 - vendor/k8s.io/cri-client/pkg/internal/log.go | 33 - vendor/k8s.io/cri-client/pkg/logs/logs.go | 487 - .../k8s.io/cri-client/pkg/logs/logs_other.go | 29 - .../cri-client/pkg/logs/logs_windows.go | 49 - vendor/k8s.io/cri-client/pkg/logs/tail.go | 62 - vendor/k8s.io/cri-client/pkg/remote_image.go | 248 - .../k8s.io/cri-client/pkg/remote_runtime.go | 914 - .../k8s.io/cri-client/pkg/util/util_unix.go | 124 - .../cri-client/pkg/util/util_unsupported.go | 36 - .../cri-client/pkg/util/util_windows.go | 108 - vendor/k8s.io/cri-client/pkg/utils.go | 79 - .../csi-translation-lib/CONTRIBUTING.md | 7 - vendor/k8s.io/csi-translation-lib/LICENSE | 201 - vendor/k8s.io/csi-translation-lib/OWNERS | 11 - vendor/k8s.io/csi-translation-lib/README.md | 30 - .../csi-translation-lib/SECURITY_CONTACTS | 18 - .../csi-translation-lib/code-of-conduct.md | 3 - .../csi-translation-lib/plugins/aws_ebs.go | 305 - .../csi-translation-lib/plugins/azure_disk.go | 309 - .../csi-translation-lib/plugins/azure_file.go | 282 - .../csi-translation-lib/plugins/const.go | 21 - .../csi-translation-lib/plugins/gce_pd.go | 400 - .../plugins/in_tree_volume.go | 398 - .../plugins/openstack_cinder.go | 185 - .../csi-translation-lib/plugins/portworx.go | 212 - .../plugins/vsphere_volume.go | 302 - .../k8s.io/csi-translation-lib/translate.go | 212 - .../dynamic-resource-allocation/LICENSE | 202 - .../api/conversion.go | 47 - .../dynamic-resource-allocation/api/doc.go | 22 - .../dynamic-resource-allocation/api/types.go | 105 - .../api/uniquestring.go | 41 - .../api/zz_generated.conversion.go | 540 - .../dynamic-resource-allocation/cel/cache.go | 81 - .../cel/compile.go | 441 - .../internal/queue/fifo.go | 112 - .../resourceclaim/devicetoleration.go | 53 - .../resourceclaim/pod.go | 48 - .../resourceclaim/resourceclaim.go | 143 - .../resourceslice/tracker/tracker.go | 798 - .../structured/allocator.go | 1318 - .../structured/doc.go | 18 - .../structured/pools.go | 197 - .../k8s.io/kube-openapi/pkg/common/common.go | 4 +- .../kube-openapi/pkg/schemaconv/openapi.go | 2 +- .../pkg/schemaconv/proto_models.go | 2 +- .../k8s.io/kube-openapi/pkg/schemaconv/smd.go | 2 +- .../kube-openapi/pkg/util/proto/document.go | 2 +- .../pkg/util/proto/document_v3.go | 2 +- .../pkg/validation/strfmt/format.go | 24 + .../strfmt/kubernetes-extensions.go | 143 + vendor/k8s.io/kube-scheduler/LICENSE | 202 - vendor/k8s.io/kube-scheduler/config/v1/doc.go | 21 - .../kube-scheduler/config/v1/register.go | 50 - .../k8s.io/kube-scheduler/config/v1/types.go | 397 - .../config/v1/types_pluginargs.go | 229 - .../config/v1/zz_generated.deepcopy.go | 609 - .../k8s.io/kube-scheduler/extender/v1/doc.go | 20 - .../kube-scheduler/extender/v1/types.go | 132 - .../extender/v1/zz_generated.deepcopy.go | 347 - .../pkg/apis/deviceplugin/v1beta1/api.pb.go | 5377 -- .../pkg/apis/deviceplugin/v1beta1/api.proto | 223 - .../apis/deviceplugin/v1beta1/constants.go | 48 - .../kubelet/pkg/apis/dra/v1alpha4/api.pb.go | 2448 - .../kubelet/pkg/apis/dra/v1alpha4/api.proto | 117 - .../pkg/apis/dra/v1alpha4/conversion.go | 187 - .../kubelet/pkg/apis/dra/v1alpha4/doc.go | 21 - .../kubelet/pkg/apis/dra/v1alpha4/types.go | 30 - .../dra/v1alpha4/zz_generated.conversion.go | 324 - .../kubelet/pkg/apis/dra/v1beta1/api.pb.go | 2449 - .../kubelet/pkg/apis/dra/v1beta1/api.proto | 117 - .../kubelet/pkg/apis/dra/v1beta1/types.go | 24 - .../pkg/apis/pluginregistration/v1/api.pb.go | 1148 - .../pkg/apis/pluginregistration/v1/api.proto | 61 - .../apis/pluginregistration/v1/constants.go | 26 - .../pkg/apis/podresources/v1/api.pb.go | 4214 -- .../pkg/apis/podresources/v1/api.proto | 121 - .../pkg/apis/podresources/v1alpha1/api.pb.go | 1387 - .../pkg/apis/podresources/v1alpha1/api.proto | 49 - .../kubernetes/pkg/api/service/warnings.go | 16 + .../k8s.io/kubernetes/pkg/api/v1/pod/util.go | 183 +- .../k8s.io/kubernetes/pkg/apis/batch/types.go | 9 +- .../kubernetes/pkg/apis/certificates/OWNERS | 8 + .../apis/{scheduling => certificates}/doc.go | 6 +- .../pkg/apis/certificates/helpers.go | 138 + .../{scheduling => certificates}/register.go | 27 +- .../kubernetes/pkg/apis/certificates/types.go | 497 + .../certificates/zz_generated.deepcopy.go | 408 + .../k8s.io/kubernetes/pkg/apis/core/types.go | 258 +- .../kubernetes/pkg/apis/core/v1/defaults.go | 30 +- .../pkg/apis/core/v1/helper/qos/qos.go | 174 - .../apis/core/v1/zz_generated.conversion.go | 218 + .../pkg/apis/core/v1/zz_generated.defaults.go | 54 + .../apis/core/v1/zz_generated.validations.go | 29 +- .../pkg/apis/core/validation/names.go | 6 + .../pkg/apis/core/validation/validation.go | 593 +- .../pkg/apis/core/zz_generated.deepcopy.go | 155 + .../kubernetes/pkg/apis/networking/types.go | 7 +- .../kubernetes/pkg/apis/scheduling/types.go | 90 - .../apis/scheduling/zz_generated.deepcopy.go | 91 - .../pkg/controller/controller_utils.go | 55 + .../kubernetes/pkg/credentialprovider/OWNERS | 8 - .../pkg/credentialprovider/config.go | 319 - .../kubernetes/pkg/credentialprovider/doc.go | 19 - .../pkg/credentialprovider/keyring.go | 367 - .../pkg/credentialprovider/provider.go | 113 - .../kubernetes/pkg/features/kube_features.go | 1298 +- .../kubernetes/pkg/kubelet/apis/config/OWNERS | 9 - .../kubernetes/pkg/kubelet/apis/config/doc.go | 20 - .../pkg/kubelet/apis/config/helpers.go | 32 - .../pkg/kubelet/apis/config/register.go | 47 - .../pkg/kubelet/apis/config/types.go | 896 - .../apis/config/zz_generated.deepcopy.go | 670 - .../kubelet/apis/podresources/.mockery.yaml | 16 - .../pkg/kubelet/apis/podresources/client.go | 72 - .../kubelet/apis/podresources/constants.go | 32 - .../kubelet/apis/podresources/server_v1.go | 157 - .../apis/podresources/server_v1alpha1.go | 82 - .../pkg/kubelet/apis/podresources/types.go | 67 - .../pkg/kubelet/cadvisor/.mockery.yaml | 10 - .../pkg/kubelet/cadvisor/cadvisor_linux.go | 185 - .../kubelet/cadvisor/cadvisor_unsupported.go | 76 - .../pkg/kubelet/cadvisor/cadvisor_windows.go | 81 - .../kubernetes/pkg/kubelet/cadvisor/doc.go | 18 - .../pkg/kubelet/cadvisor/helpers_linux.go | 63 - .../kubelet/cadvisor/helpers_unsupported.go | 39 - .../kubernetes/pkg/kubelet/cadvisor/types.go | 56 - .../kubernetes/pkg/kubelet/cadvisor/util.go | 85 - .../pkg/kubelet/checkpointmanager/README.md | 25 - .../checkpointmanager/checkpoint_manager.go | 110 - .../checkpointmanager/checksum/checksum.go | 48 - .../checkpointmanager/errors/errors.go | 45 - .../kubernetes/pkg/kubelet/cm/.mockery.yaml | 11 - .../k8s.io/kubernetes/pkg/kubelet/cm/OWNERS | 14 - .../pkg/kubelet/cm/admission/errors.go | 62 - .../pkg/kubelet/cm/cgroup_manager_linux.go | 484 - .../kubelet/cm/cgroup_manager_unsupported.go | 120 - .../pkg/kubelet/cm/cgroup_v1_manager_linux.go | 145 - .../pkg/kubelet/cm/cgroup_v2_manager_linux.go | 181 - .../pkg/kubelet/cm/container_manager.go | 319 - .../pkg/kubelet/cm/container_manager_linux.go | 1057 - .../pkg/kubelet/cm/container_manager_stub.go | 219 - .../cm/container_manager_unsupported.go | 49 - .../kubelet/cm/container_manager_windows.go | 379 - .../kubelet/cm/containermap/container_map.go | 87 - .../pkg/kubelet/cm/cpumanager/OWNERS | 10 - .../kubelet/cm/cpumanager/cpu_assignment.go | 1097 - .../pkg/kubelet/cm/cpumanager/cpu_manager.go | 527 - .../cm/cpumanager/cpu_manager_others.go | 43 - .../cm/cpumanager/cpu_manager_windows.go | 49 - .../kubelet/cm/cpumanager/fake_cpu_manager.go | 98 - .../pkg/kubelet/cm/cpumanager/policy.go | 45 - .../pkg/kubelet/cm/cpumanager/policy_none.go | 76 - .../kubelet/cm/cpumanager/policy_options.go | 187 - .../kubelet/cm/cpumanager/policy_static.go | 816 - .../kubelet/cm/cpumanager/state/checkpoint.go | 135 - .../pkg/kubelet/cm/cpumanager/state/state.go | 58 - .../cm/cpumanager/state/state_checkpoint.go | 250 - .../kubelet/cm/cpumanager/state/state_mem.go | 117 - .../cm/cpumanager/topology/alignment.go | 78 - .../pkg/kubelet/cm/cpumanager/topology/doc.go | 18 - .../cm/cpumanager/topology/topology.go | 398 - .../pkg/kubelet/cm/devicemanager/OWNERS | 8 - .../cm/devicemanager/checkpoint/checkpoint.go | 109 - .../pkg/kubelet/cm/devicemanager/endpoint.go | 123 - .../pkg/kubelet/cm/devicemanager/manager.go | 1185 - .../cm/devicemanager/plugin/v1beta1/api.go | 49 - .../cm/devicemanager/plugin/v1beta1/client.go | 145 - .../devicemanager/plugin/v1beta1/handler.go | 124 - .../cm/devicemanager/plugin/v1beta1/server.go | 226 - .../cm/devicemanager/plugin/v1beta1/stub.go | 388 - .../kubelet/cm/devicemanager/pod_devices.go | 454 - .../cm/devicemanager/topology_hints.go | 252 - .../pkg/kubelet/cm/devicemanager/types.go | 123 - .../k8s.io/kubernetes/pkg/kubelet/cm/doc.go | 21 - .../kubernetes/pkg/kubelet/cm/dra/OWNERS | 2 - .../pkg/kubelet/cm/dra/claiminfo.go | 222 - .../kubernetes/pkg/kubelet/cm/dra/manager.go | 566 - .../pkg/kubelet/cm/dra/plugin/plugin.go | 181 - .../kubelet/cm/dra/plugin/plugins_store.go | 96 - .../pkg/kubelet/cm/dra/plugin/registration.go | 345 - .../pkg/kubelet/cm/dra/state/checkpoint.go | 107 - .../pkg/kubelet/cm/dra/state/checkpointer.go | 98 - .../pkg/kubelet/cm/dra/state/state.go | 59 - .../cm/dra/state/zz_generated.deepcopy.go | 105 - .../kubernetes/pkg/kubelet/cm/dra/types.go | 61 - .../kubelet/cm/dra/zz_generated.deepcopy.go | 39 - .../pkg/kubelet/cm/fake_container_manager.go | 278 - .../cm/fake_internal_container_lifecycle.go | 40 - .../kubelet/cm/fake_pod_container_manager.go | 127 - .../kubernetes/pkg/kubelet/cm/helpers.go | 89 - .../pkg/kubelet/cm/helpers_linux.go | 343 - .../pkg/kubelet/cm/helpers_unsupported.go | 76 - .../cm/internal_container_lifecycle.go | 56 - .../cm/internal_container_lifecycle_linux.go | 51 - ...nternal_container_lifecycle_unsupported.go | 29 - .../internal_container_lifecycle_windows.go | 141 - .../cm/memorymanager/fake_memory_manager.go | 94 - .../cm/memorymanager/memory_manager.go | 468 - .../pkg/kubelet/cm/memorymanager/policy.go | 46 - .../cm/memorymanager/policy_best_effort.go | 80 - .../kubelet/cm/memorymanager/policy_none.go | 72 - .../kubelet/cm/memorymanager/policy_static.go | 1066 - .../cm/memorymanager/state/checkpoint.go | 65 - .../kubelet/cm/memorymanager/state/state.go | 130 - .../memorymanager/state/state_checkpoint.go | 184 - .../cm/memorymanager/state/state_mem.go | 124 - .../cm/node_container_manager_linux.go | 328 - .../kubelet/cm/pod_container_manager_linux.go | 362 - .../kubelet/cm/pod_container_manager_stub.go | 75 - .../kubelet/cm/qos_container_manager_linux.go | 407 - .../pkg/kubelet/cm/resourceupdates/updates.go | 25 - .../pkg/kubelet/cm/topologymanager/OWNERS | 9 - .../cm/topologymanager/bitmask/bitmask.go | 222 - .../topologymanager/fake_topology_manager.go | 83 - .../kubelet/cm/topologymanager/numa_info.go | 109 - .../pkg/kubelet/cm/topologymanager/policy.go | 361 - .../cm/topologymanager/policy_best_effort.go | 49 - .../kubelet/cm/topologymanager/policy_none.go | 41 - .../cm/topologymanager/policy_options.go | 105 - .../cm/topologymanager/policy_restricted.go | 47 - .../policy_single_numa_node.go | 75 - .../pkg/kubelet/cm/topologymanager/scope.go | 158 - .../cm/topologymanager/scope_container.go | 93 - .../kubelet/cm/topologymanager/scope_none.go | 46 - .../kubelet/cm/topologymanager/scope_pod.go | 94 - .../cm/topologymanager/topology_manager.go | 234 - .../k8s.io/kubernetes/pkg/kubelet/cm/types.go | 140 - .../pkg/kubelet/cm/util/cgroups_linux.go | 94 - .../kubelet/cm/util/cgroups_unsupported.go | 25 - .../pkg/kubelet/config/apiserver.go | 68 - .../kubernetes/pkg/kubelet/config/common.go | 197 - .../kubernetes/pkg/kubelet/config/config.go | 500 - .../kubernetes/pkg/kubelet/config/defaults.go | 34 - .../kubernetes/pkg/kubelet/config/doc.go | 18 - .../kubernetes/pkg/kubelet/config/file.go | 245 - .../pkg/kubelet/config/file_linux.go | 154 - .../pkg/kubelet/config/file_unsupported.go | 34 - .../kubernetes/pkg/kubelet/config/flags.go | 59 - .../kubernetes/pkg/kubelet/config/http.go | 143 - .../kubernetes/pkg/kubelet/config/mux.go | 83 - .../kubernetes/pkg/kubelet/config/sources.go | 67 - .../pkg/kubelet/container/.mockery.yaml | 18 - .../kubernetes/pkg/kubelet/container/cache.go | 214 - .../pkg/kubelet/container/container_gc.go | 88 - .../pkg/kubelet/container/helpers.go | 444 - .../kubernetes/pkg/kubelet/container/os.go | 124 - .../kubernetes/pkg/kubelet/container/ref.go | 78 - .../pkg/kubelet/container/runtime.go | 795 - .../pkg/kubelet/container/runtime_cache.go | 97 - .../kubelet/container/runtime_cache_fake.go | 50 - .../pkg/kubelet/container/sync_result.go | 138 - .../kubernetes/pkg/kubelet/events/event.go | 1 + .../pkg/kubelet/eviction/api/types.go | 117 - .../pkg/kubelet/kuberuntime/util/util.go | 127 - .../admission_failure_handler_stub.go | 37 - .../kubernetes/pkg/kubelet/lifecycle/doc.go | 19 - .../pkg/kubelet/lifecycle/handlers.go | 243 - .../pkg/kubelet/lifecycle/interfaces.go | 122 - .../pkg/kubelet/lifecycle/predicate.go | 412 - .../kubernetes/pkg/kubelet/metrics/OWNERS | 3 - .../kubernetes/pkg/kubelet/metrics/metrics.go | 1209 - .../cache/actual_state_of_world.go | 145 - .../cache/desired_state_of_world.go | 172 - .../pkg/kubelet/pluginmanager/cache/types.go | 60 - .../k8s.io/kubernetes/pkg/kubelet/qos/doc.go | 25 - .../kubernetes/pkg/kubelet/qos/helpers.go | 71 - .../kubernetes/pkg/kubelet/qos/policy.go | 135 - .../pkg/kubelet/stats/pidlimit/pidlimit.go | 26 - .../kubelet/stats/pidlimit/pidlimit_linux.go | 87 - .../stats/pidlimit/pidlimit_unsupported.go | 29 - .../pkg/kubelet/status/.mockery.yaml | 10 - .../kubernetes/pkg/kubelet/status/generate.go | 302 - .../pkg/kubelet/status/status_manager.go | 1195 - .../kubernetes/pkg/kubelet/types/constants.go | 40 - .../kubernetes/pkg/kubelet/types/doc.go | 18 - .../pkg/kubelet/types/pod_status.go | 53 - .../pkg/kubelet/types/pod_update.go | 206 - .../kubernetes/pkg/kubelet/types/types.go | 116 - .../pkg/kubelet/util/boottime_util_darwin.go | 45 - .../pkg/kubelet/util/boottime_util_freebsd.go | 40 - .../pkg/kubelet/util/boottime_util_linux.go | 74 - .../k8s.io/kubernetes/pkg/kubelet/util/doc.go | 18 - .../kubernetes/pkg/kubelet/util/format/pod.go | 41 - .../util/node_startup_latency_tracker.go | 103 - .../kubernetes/pkg/kubelet/util/nodelease.go | 55 - .../util/pod_startup_latency_tracker.go | 196 - .../kubernetes/pkg/kubelet/util/store/doc.go | 18 - .../pkg/kubelet/util/store/filestore.go | 158 - .../pkg/kubelet/util/store/store.go | 64 - .../pkg/kubelet/util/swap/swap_util.go | 149 - .../kubernetes/pkg/kubelet/util/util.go | 62 - .../kubernetes/pkg/kubelet/util/util_linux.go | 29 - .../pkg/kubelet/util/util_others.go | 25 - .../kubernetes/pkg/kubelet/util/util_unix.go | 44 - .../pkg/kubelet/util/util_unsupported.go | 44 - .../pkg/kubelet/util/util_windows.go | 80 - .../pkg/kubelet/winstats/cpu_topology.go | 264 - .../kubernetes/pkg/kubelet/winstats/doc.go | 18 - .../pkg/kubelet/winstats/network_stats.go | 313 - .../winstats/perfcounter_nodestats_windows.go | 358 - .../pkg/kubelet/winstats/perfcounters.go | 136 - .../pkg/kubelet/winstats/version.go | 86 - .../pkg/kubelet/winstats/winstats.go | 188 - .../kubernetes/pkg/probe/dialer_others.go | 42 - .../kubernetes/pkg/probe/dialer_windows.go | 42 - vendor/k8s.io/kubernetes/pkg/probe/doc.go | 18 - .../k8s.io/kubernetes/pkg/probe/http/http.go | 141 - .../kubernetes/pkg/probe/http/request.go | 119 - vendor/k8s.io/kubernetes/pkg/probe/probe.go | 31 - vendor/k8s.io/kubernetes/pkg/probe/util.go | 57 - vendor/k8s.io/kubernetes/pkg/scheduler/OWNERS | 8 - .../pkg/scheduler/apis/config/OWNERS | 11 - .../pkg/scheduler/apis/config/doc.go | 20 - .../pkg/scheduler/apis/config/register.go | 50 - .../scheduler/apis/config/scheme/scheme.go | 46 - .../pkg/scheduler/apis/config/types.go | 336 - .../scheduler/apis/config/types_pluginargs.go | 218 - .../scheduler/apis/config/v1/conversion.go | 107 - .../apis/config/v1/default_plugins.go | 157 - .../pkg/scheduler/apis/config/v1/defaults.go | 244 - .../pkg/scheduler/apis/config/v1/doc.go | 24 - .../pkg/scheduler/apis/config/v1/register.go | 42 - .../apis/config/v1/zz_generated.conversion.go | 946 - .../apis/config/v1/zz_generated.deepcopy.go | 22 - .../apis/config/v1/zz_generated.defaults.go | 73 - .../apis/config/validation/validation.go | 296 - .../validation/validation_pluginargs.go | 329 - .../apis/config/zz_generated.deepcopy.go | 562 - .../pkg/scheduler/backend/cache/cache.go | 768 - .../backend/cache/debugger/comparer.go | 135 - .../backend/cache/debugger/debugger.go | 76 - .../backend/cache/debugger/dumper.go | 88 - .../backend/cache/debugger/signal.go | 26 - .../backend/cache/debugger/signal_windows.go | 23 - .../pkg/scheduler/backend/cache/interface.go | 123 - .../pkg/scheduler/backend/cache/node_tree.go | 143 - .../pkg/scheduler/backend/cache/snapshot.go | 198 - .../pkg/scheduler/backend/heap/heap.go | 244 - .../scheduler/backend/queue/active_queue.go | 498 - .../scheduler/backend/queue/backoff_queue.go | 405 - .../pkg/scheduler/backend/queue/nominator.go | 195 - .../backend/queue/scheduling_queue.go | 1401 - .../pkg/scheduler/backend/queue/testing.go | 63 - .../kubernetes/pkg/scheduler/eventhandlers.go | 690 - .../kubernetes/pkg/scheduler/extender.go | 456 - .../pkg/scheduler/framework/cycle_state.go | 123 - .../pkg/scheduler/framework/events.go | 231 - .../pkg/scheduler/framework/extender.go | 79 - .../pkg/scheduler/framework/interface.go | 954 - .../pkg/scheduler/framework/listers.go | 116 - .../framework/parallelize/error_channel.go | 59 - .../framework/parallelize/parallelism.go | 78 - .../pkg/scheduler/framework/plugins/README.md | 3 - .../plugins/defaultbinder/default_binder.go | 63 - .../defaultpreemption/default_preemption.go | 368 - .../framework/plugins/dynamicresources/OWNERS | 9 - .../dynamicresources/allocateddevices.go | 175 - .../plugins/dynamicresources/dra_manager.go | 228 - .../dynamicresources/dynamicresources.go | 910 - .../framework/plugins/feature/feature.go | 38 - .../plugins/helper/normalize_score.go | 55 - .../framework/plugins/helper/shape_score.go | 52 - .../framework/plugins/helper/spread.go | 116 - .../framework/plugins/helper/taint.go | 28 - .../plugins/imagelocality/image_locality.go | 126 - .../plugins/interpodaffinity/filtering.go | 435 - .../plugins/interpodaffinity/plugin.go | 299 - .../plugins/interpodaffinity/scoring.go | 294 - .../framework/plugins/names/names.go | 39 - .../plugins/nodeaffinity/node_affinity.go | 364 - .../framework/plugins/nodename/node_name.go | 89 - .../framework/plugins/nodeports/node_ports.go | 191 - .../noderesources/balanced_allocation.go | 179 - .../framework/plugins/noderesources/fit.go | 591 - .../plugins/noderesources/least_allocated.go | 61 - .../plugins/noderesources/most_allocated.go | 65 - .../requested_to_capacity_ratio.go | 73 - .../noderesources/resource_allocation.go | 157 - .../plugins/noderesources/test_util.go | 57 - .../nodeunschedulable/node_unschedulable.go | 154 - .../framework/plugins/nodevolumelimits/OWNERS | 10 - .../framework/plugins/nodevolumelimits/csi.go | 621 - .../plugins/nodevolumelimits/utils.go | 71 - .../plugins/podtopologyspread/common.go | 169 - .../plugins/podtopologyspread/filtering.go | 367 - .../plugins/podtopologyspread/plugin.go | 351 - .../plugins/podtopologyspread/scoring.go | 303 - .../plugins/queuesort/priority_sort.go | 53 - .../scheduler/framework/plugins/registry.go | 89 - .../schedulinggates/scheduling_gates.go | 94 - .../tainttoleration/taint_toleration.go | 229 - .../framework/plugins/volumebinding/OWNERS | 10 - .../plugins/volumebinding/assume_cache.go | 131 - .../framework/plugins/volumebinding/binder.go | 1124 - .../plugins/volumebinding/fake_binder.go | 75 - .../plugins/volumebinding/metrics/metrics.go | 55 - .../framework/plugins/volumebinding/scorer.go | 54 - .../plugins/volumebinding/test_utils.go | 217 - .../plugins/volumebinding/volume_binding.go | 630 - .../plugins/volumerestrictions/OWNERS | 10 - .../volumerestrictions/volume_restrictions.go | 426 - .../framework/plugins/volumezone/OWNERS | 10 - .../plugins/volumezone/volume_zone.go | 410 - .../framework/preemption/preemption.go | 739 - .../scheduler/framework/runtime/framework.go | 1672 - .../framework/runtime/instrumented_plugins.go | 83 - .../scheduler/framework/runtime/registry.go | 101 - .../framework/runtime/waiting_pods_map.go | 165 - .../pkg/scheduler/framework/types.go | 1334 - .../pkg/scheduler/metrics/metric_recorder.go | 224 - .../pkg/scheduler/metrics/metrics.go | 411 - .../pkg/scheduler/metrics/profile_metrics.go | 48 - .../pkg/scheduler/profile/profile.go | 130 - .../kubernetes/pkg/scheduler/schedule_one.go | 1123 - .../kubernetes/pkg/scheduler/scheduler.go | 617 - .../util/assumecache/assume_cache.go | 531 - .../pkg/scheduler/util/pod_resources.go | 32 - .../pkg/scheduler/util/queue/fifo.go | 110 - .../kubernetes/pkg/scheduler/util/utils.go | 226 - .../kubernetes/pkg/security/apparmor/OWNERS | 10 - .../pkg/security/apparmor/helpers.go | 99 - .../pkg/security/apparmor/validate.go | 101 - .../security/apparmor/validate_disabled.go | 25 - .../pkg/{probe => securitycontext}/OWNERS | 0 .../pkg/securitycontext/accessors.go | 19 + .../pkg/securitycontext/util_linux.go | 4 +- .../pkg/util/filesystem/defaultfs.go | 172 - .../pkg/util/filesystem/filesystem.go | 52 - .../kubernetes/pkg/util/filesystem/util.go | 27 - .../pkg/util/filesystem/util_unix.go | 53 - .../pkg/util/filesystem/util_windows.go | 263 - .../kubernetes/pkg/util/filesystem/watcher.go | 216 - .../k8s.io/kubernetes/pkg/util/kernel/OWNERS | 8 - .../kubernetes/pkg/util/kernel/constants.go | 60 - .../kubernetes/pkg/util/kernel/version.go | 48 - vendor/k8s.io/kubernetes/pkg/util/oom/doc.go | 18 - vendor/k8s.io/kubernetes/pkg/util/oom/oom.go | 26 - .../kubernetes/pkg/util/oom/oom_fake.go | 35 - .../kubernetes/pkg/util/oom/oom_linux.go | 130 - .../pkg/util/oom/oom_unsupported.go | 41 - vendor/k8s.io/kubernetes/pkg/util/pod/pod.go | 81 - .../k8s.io/kubernetes/pkg/util/slice/slice.go | 75 - .../k8s.io/kubernetes/pkg/volume/plugins.go | 18 +- .../pkg/volume/util/attach_limit.go | 22 - .../kubernetes/pkg/volume/util/resize_util.go | 5 +- .../kubernetes/pkg/volume/util/types/types.go | 4 + .../k8s.io/kubernetes/pkg/volume/util/util.go | 8 - .../volumepathhandler/volume_path_handler.go | 8 +- vendor/k8s.io/kubernetes/pkg/volume/volume.go | 9 + .../kubernetes/pkg/volume/volume_linux.go | 4 +- .../pkg/volume/volume_unsupported.go | 6 +- .../debug/resource_usage_gatherer.go | 16 +- .../test/e2e/framework/framework.go | 5 + .../kubernetes/test/e2e/framework/get.go | 2 + .../test/e2e/framework/ginkgowrapper.go | 11 +- .../test/e2e/framework/kubectl/builder.go | 16 +- .../test/e2e/framework/pod/delete.go | 18 +- .../test/e2e/framework/pod/pod_client.go | 13 + .../test/e2e/framework/pod/resize.go | 537 - .../test/e2e/framework/pod/resource.go | 21 +- .../test/e2e/framework/pod/utils.go | 110 +- .../kubernetes/test/e2e/framework/pv/wait.go | 9 +- .../test/e2e/framework/test_context.go | 14 + .../kubernetes/test/e2e/framework/util.go | 1 + .../test/e2e/storage/utils/create.go | 9 +- .../kubernetes/test/e2e/storage/utils/file.go | 41 + .../kubernetes/test/e2e/storage/utils/pod.go | 10 +- .../gpu/gce/nvidia-driver-installer.yaml | 2 +- .../legacy/redis-master-controller.yaml | 2 +- .../legacy/redis-slave-controller.yaml | 2 +- .../kubectl/agnhost-primary-pod.yaml | 4 +- .../statefulset/nginx/service.yaml | 13 - .../statefulset/nginx/statefulset.yaml | 34 - .../statefulset/redis/service.yaml | 16 - .../statefulset/redis/statefulset.yaml | 81 - ...lator.storage.k8s.io_volumepopulators.yaml | 1 - .../csi-hostpath-plugin.yaml | 2 +- .../run_group_snapshot_e2e.sh | 8 +- .../storage-csi/gce-pd/controller_ss.yaml | 2 +- .../hostpath/csi-hostpath-plugin.yaml | 2 +- .../mock/csi-mock-driver-snapshotter.yaml | 2 +- .../kubernetes/test/utils/image/manifest.go | 13 +- .../k8s.io/kubernetes/test/utils/runners.go | 43 +- .../third_party/forked/golang/LICENSE | 27 - .../third_party/forked/golang/PATENTS | 22 - .../forked/golang/expansion/expand.go | 102 - .../third_party/forked/libcontainer/LICENSE | 191 - .../third_party/forked/libcontainer/NOTICE | 17 - .../libcontainer/apparmor/apparmor_linux.go | 22 - .../apparmor/apparmor_unsupported.go | 8 - .../forked/libcontainer/utils/utils.go | 35 - vendor/k8s.io/utils/cpuset/OWNERS | 8 - vendor/k8s.io/utils/cpuset/cpuset.go | 256 - vendor/k8s.io/utils/inotify/LICENSE | 27 - vendor/k8s.io/utils/inotify/PATENTS | 22 - vendor/k8s.io/utils/inotify/README.md | 5 - vendor/k8s.io/utils/inotify/inotify.go | 45 - vendor/k8s.io/utils/inotify/inotify_linux.go | 315 - vendor/k8s.io/utils/inotify/inotify_others.go | 54 - vendor/modules.txt | 343 +- .../structured-merge-diff/v6}/LICENSE | 0 .../structured-merge-diff/v6/schema/doc.go | 28 + .../v6/schema/elements.go | 375 + .../structured-merge-diff/v6/schema/equals.go | 202 + .../v6/schema/schemaschema.go | 165 + 1179 files changed, 15440 insertions(+), 235219 deletions(-) delete mode 100644 vendor/github.com/JeffAshton/win_pdh/AUTHORS delete mode 100644 vendor/github.com/JeffAshton/win_pdh/LICENSE delete mode 100644 vendor/github.com/JeffAshton/win_pdh/README.mdown delete mode 100644 vendor/github.com/JeffAshton/win_pdh/pdh.go delete mode 100644 vendor/github.com/Microsoft/go-winio/.gitattributes delete mode 100644 vendor/github.com/Microsoft/go-winio/.gitignore delete mode 100644 vendor/github.com/Microsoft/go-winio/.golangci.yml delete mode 100644 vendor/github.com/Microsoft/go-winio/CODEOWNERS delete mode 100644 vendor/github.com/Microsoft/go-winio/LICENSE delete mode 100644 vendor/github.com/Microsoft/go-winio/README.md delete mode 100644 vendor/github.com/Microsoft/go-winio/SECURITY.md delete mode 100644 vendor/github.com/Microsoft/go-winio/backup.go delete mode 100644 vendor/github.com/Microsoft/go-winio/doc.go delete mode 100644 vendor/github.com/Microsoft/go-winio/ea.go delete mode 100644 vendor/github.com/Microsoft/go-winio/file.go delete mode 100644 vendor/github.com/Microsoft/go-winio/fileinfo.go delete mode 100644 vendor/github.com/Microsoft/go-winio/hvsock.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/fs/doc.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/fs/fs.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/fs/security.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/socket/socket.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go delete mode 100644 vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go delete mode 100644 vendor/github.com/Microsoft/go-winio/pipe.go delete mode 100644 vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go delete mode 100644 vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go delete mode 100644 vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go delete mode 100644 vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go delete mode 100644 vendor/github.com/Microsoft/go-winio/privilege.go delete mode 100644 vendor/github.com/Microsoft/go-winio/reparse.go delete mode 100644 vendor/github.com/Microsoft/go-winio/sd.go delete mode 100644 vendor/github.com/Microsoft/go-winio/syscall.go delete mode 100644 vendor/github.com/Microsoft/go-winio/zsyscall_windows.go delete mode 100644 vendor/github.com/containerd/containerd/api/LICENSE delete mode 100644 vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto delete mode 100644 vendor/github.com/containerd/containerd/api/services/containers/v1/containers_grpc.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/containers/v1/containers_ttrpc.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/containers/v1/doc.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/tasks/v1/doc.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto delete mode 100644 vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_grpc.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_ttrpc.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/version/v1/doc.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/version/v1/version.proto delete mode 100644 vendor/github.com/containerd/containerd/api/services/version/v1/version_grpc.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/services/version/v1/version_ttrpc.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/descriptor.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/descriptor.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/doc.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/event.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/event.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/fieldpath.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/fieldpath.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/introspection.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/introspection.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/metrics.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/metrics.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/mount.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/mount.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/platform.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/platform.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/platform_helpers.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/sandbox.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/sandbox.proto delete mode 100644 vendor/github.com/containerd/containerd/api/types/task/doc.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/task/task.pb.go delete mode 100644 vendor/github.com/containerd/containerd/api/types/task/task.proto delete mode 100644 vendor/github.com/containerd/errdefs/LICENSE delete mode 100644 vendor/github.com/containerd/errdefs/README.md delete mode 100644 vendor/github.com/containerd/errdefs/errors.go delete mode 100644 vendor/github.com/containerd/errdefs/pkg/LICENSE delete mode 100644 vendor/github.com/containerd/errdefs/pkg/errgrpc/grpc.go delete mode 100644 vendor/github.com/containerd/errdefs/pkg/internal/cause/cause.go delete mode 100644 vendor/github.com/containerd/errdefs/pkg/internal/types/collapsible.go delete mode 100644 vendor/github.com/containerd/errdefs/resolve.go delete mode 100644 vendor/github.com/containerd/log/.golangci.yml delete mode 100644 vendor/github.com/containerd/log/LICENSE delete mode 100644 vendor/github.com/containerd/log/README.md delete mode 100644 vendor/github.com/containerd/log/context.go delete mode 100644 vendor/github.com/containerd/ttrpc/.gitattributes delete mode 100644 vendor/github.com/containerd/ttrpc/.gitignore delete mode 100644 vendor/github.com/containerd/ttrpc/.golangci.yml delete mode 100644 vendor/github.com/containerd/ttrpc/LICENSE delete mode 100644 vendor/github.com/containerd/ttrpc/Makefile delete mode 100644 vendor/github.com/containerd/ttrpc/PROTOCOL.md delete mode 100644 vendor/github.com/containerd/ttrpc/Protobuild.toml delete mode 100644 vendor/github.com/containerd/ttrpc/README.md delete mode 100644 vendor/github.com/containerd/ttrpc/channel.go delete mode 100644 vendor/github.com/containerd/ttrpc/client.go delete mode 100644 vendor/github.com/containerd/ttrpc/codec.go delete mode 100644 vendor/github.com/containerd/ttrpc/config.go delete mode 100644 vendor/github.com/containerd/ttrpc/doc.go delete mode 100644 vendor/github.com/containerd/ttrpc/errors.go delete mode 100644 vendor/github.com/containerd/ttrpc/handshake.go delete mode 100644 vendor/github.com/containerd/ttrpc/interceptor.go delete mode 100644 vendor/github.com/containerd/ttrpc/metadata.go delete mode 100644 vendor/github.com/containerd/ttrpc/request.pb.go delete mode 100644 vendor/github.com/containerd/ttrpc/request.proto delete mode 100644 vendor/github.com/containerd/ttrpc/server.go delete mode 100644 vendor/github.com/containerd/ttrpc/services.go delete mode 100644 vendor/github.com/containerd/ttrpc/stream.go delete mode 100644 vendor/github.com/containerd/ttrpc/stream_server.go delete mode 100644 vendor/github.com/containerd/ttrpc/test.proto delete mode 100644 vendor/github.com/containerd/ttrpc/unixcreds_linux.go delete mode 100644 vendor/github.com/containerd/typeurl/v2/.gitignore delete mode 100644 vendor/github.com/containerd/typeurl/v2/LICENSE delete mode 100644 vendor/github.com/containerd/typeurl/v2/README.md delete mode 100644 vendor/github.com/containerd/typeurl/v2/doc.go delete mode 100644 vendor/github.com/containerd/typeurl/v2/types.go delete mode 100644 vendor/github.com/containerd/typeurl/v2/types_gogo.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/LICENSE delete mode 100644 vendor/github.com/coreos/go-systemd/v22/NOTICE delete mode 100644 vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/dbus/methods.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/dbus/properties.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/dbus/set.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go delete mode 100644 vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/.golangci.yml delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/README.md delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/VERSION delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/codecov.yml delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/doc.go delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/join.go delete mode 100644 vendor/github.com/cyphar/filepath-securejoin/vfs.go delete mode 100644 vendor/github.com/docker/go-units/CONTRIBUTING.md delete mode 100644 vendor/github.com/docker/go-units/LICENSE delete mode 100644 vendor/github.com/docker/go-units/MAINTAINERS delete mode 100644 vendor/github.com/docker/go-units/README.md delete mode 100644 vendor/github.com/docker/go-units/circle.yml delete mode 100644 vendor/github.com/docker/go-units/duration.go delete mode 100644 vendor/github.com/docker/go-units/size.go delete mode 100644 vendor/github.com/docker/go-units/ulimit.go delete mode 100644 vendor/github.com/euank/go-kmsg-parser/kmsgparser/kmsgparser.go delete mode 100644 vendor/github.com/euank/go-kmsg-parser/kmsgparser/log.go delete mode 100644 vendor/github.com/fxamacker/cbor/v2/encode_map_go117.go create mode 100644 vendor/github.com/fxamacker/cbor/v2/omitzero_go124.go create mode 100644 vendor/github.com/fxamacker/cbor/v2/omitzero_pre_go124.go delete mode 100644 vendor/github.com/godbus/dbus/v5/CONTRIBUTING.md delete mode 100644 vendor/github.com/godbus/dbus/v5/LICENSE delete mode 100644 vendor/github.com/godbus/dbus/v5/MAINTAINERS delete mode 100644 vendor/github.com/godbus/dbus/v5/README.md delete mode 100644 vendor/github.com/godbus/dbus/v5/auth.go delete mode 100644 vendor/github.com/godbus/dbus/v5/auth_anonymous.go delete mode 100644 vendor/github.com/godbus/dbus/v5/auth_external.go delete mode 100644 vendor/github.com/godbus/dbus/v5/auth_sha1.go delete mode 100644 vendor/github.com/godbus/dbus/v5/call.go delete mode 100644 vendor/github.com/godbus/dbus/v5/conn.go delete mode 100644 vendor/github.com/godbus/dbus/v5/conn_darwin.go delete mode 100644 vendor/github.com/godbus/dbus/v5/conn_other.go delete mode 100644 vendor/github.com/godbus/dbus/v5/conn_unix.go delete mode 100644 vendor/github.com/godbus/dbus/v5/conn_windows.go delete mode 100644 vendor/github.com/godbus/dbus/v5/dbus.go delete mode 100644 vendor/github.com/godbus/dbus/v5/decoder.go delete mode 100644 vendor/github.com/godbus/dbus/v5/default_handler.go delete mode 100644 vendor/github.com/godbus/dbus/v5/doc.go delete mode 100644 vendor/github.com/godbus/dbus/v5/encoder.go delete mode 100644 vendor/github.com/godbus/dbus/v5/escape.go delete mode 100644 vendor/github.com/godbus/dbus/v5/export.go delete mode 100644 vendor/github.com/godbus/dbus/v5/homedir.go delete mode 100644 vendor/github.com/godbus/dbus/v5/match.go delete mode 100644 vendor/github.com/godbus/dbus/v5/message.go delete mode 100644 vendor/github.com/godbus/dbus/v5/object.go delete mode 100644 vendor/github.com/godbus/dbus/v5/sequence.go delete mode 100644 vendor/github.com/godbus/dbus/v5/sequential_handler.go delete mode 100644 vendor/github.com/godbus/dbus/v5/server_interfaces.go delete mode 100644 vendor/github.com/godbus/dbus/v5/sig.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_darwin.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_generic.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_nonce_tcp.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_tcp.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_unix.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_unixcred_dragonfly.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_unixcred_freebsd.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_unixcred_linux.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_unixcred_netbsd.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_unixcred_openbsd.go delete mode 100644 vendor/github.com/godbus/dbus/v5/transport_zos.go delete mode 100644 vendor/github.com/godbus/dbus/v5/variant.go delete mode 100644 vendor/github.com/godbus/dbus/v5/variant_lexer.go delete mode 100644 vendor/github.com/godbus/dbus/v5/variant_parser.go delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/Makefile delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/doc.go delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/gogo.pb.golden delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/gogo.proto delete mode 100644 vendor/github.com/gogo/protobuf/gogoproto/helper.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/Makefile delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor.pb.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/descriptor_gostring.gen.go delete mode 100644 vendor/github.com/gogo/protobuf/protoc-gen-gogo/descriptor/helper.go delete mode 100644 vendor/github.com/google/cadvisor/AUTHORS delete mode 100644 vendor/github.com/google/cadvisor/LICENSE delete mode 100644 vendor/github.com/google/cadvisor/cache/memory/memory.go delete mode 100644 vendor/github.com/google/cadvisor/collector/collector_manager.go delete mode 100644 vendor/github.com/google/cadvisor/collector/config.go delete mode 100644 vendor/github.com/google/cadvisor/collector/fakes.go delete mode 100644 vendor/github.com/google/cadvisor/collector/generic_collector.go delete mode 100644 vendor/github.com/google/cadvisor/collector/prometheus_collector.go delete mode 100644 vendor/github.com/google/cadvisor/collector/types.go delete mode 100644 vendor/github.com/google/cadvisor/collector/util.go delete mode 100644 vendor/github.com/google/cadvisor/container/common/container_hints.go delete mode 100644 vendor/github.com/google/cadvisor/container/common/fsHandler.go delete mode 100644 vendor/github.com/google/cadvisor/container/common/helpers.go delete mode 100644 vendor/github.com/google/cadvisor/container/common/inotify_watcher.go delete mode 100644 vendor/github.com/google/cadvisor/container/container.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/client.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/containers/containers.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/factory.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/grpc.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/handler.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/identifiers/validate.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/install/install.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/namespaces/context.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/namespaces/grpc.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/namespaces/store.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/namespaces/ttrpc.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_unix.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/pkg/dialer/dialer_windows.go delete mode 100644 vendor/github.com/google/cadvisor/container/containerd/plugin.go delete mode 100644 vendor/github.com/google/cadvisor/container/crio/client.go delete mode 100644 vendor/github.com/google/cadvisor/container/crio/factory.go delete mode 100644 vendor/github.com/google/cadvisor/container/crio/handler.go delete mode 100644 vendor/github.com/google/cadvisor/container/crio/install/install.go delete mode 100644 vendor/github.com/google/cadvisor/container/crio/plugin.go delete mode 100644 vendor/github.com/google/cadvisor/container/factory.go delete mode 100644 vendor/github.com/google/cadvisor/container/libcontainer/handler.go delete mode 100644 vendor/github.com/google/cadvisor/container/libcontainer/helpers.go delete mode 100644 vendor/github.com/google/cadvisor/container/raw/factory.go delete mode 100644 vendor/github.com/google/cadvisor/container/raw/handler.go delete mode 100644 vendor/github.com/google/cadvisor/container/raw/watcher.go delete mode 100644 vendor/github.com/google/cadvisor/container/systemd/factory.go delete mode 100644 vendor/github.com/google/cadvisor/container/systemd/install/install.go delete mode 100644 vendor/github.com/google/cadvisor/container/systemd/plugin.go delete mode 100644 vendor/github.com/google/cadvisor/devicemapper/dmsetup_client.go delete mode 100644 vendor/github.com/google/cadvisor/devicemapper/doc.go delete mode 100644 vendor/github.com/google/cadvisor/devicemapper/thin_ls_client.go delete mode 100644 vendor/github.com/google/cadvisor/devicemapper/thin_pool_watcher.go delete mode 100644 vendor/github.com/google/cadvisor/devicemapper/util.go delete mode 100644 vendor/github.com/google/cadvisor/events/handler.go delete mode 100644 vendor/github.com/google/cadvisor/fs/fs.go delete mode 100644 vendor/github.com/google/cadvisor/fs/types.go delete mode 100644 vendor/github.com/google/cadvisor/info/v1/container.go delete mode 100644 vendor/github.com/google/cadvisor/info/v1/docker.go delete mode 100644 vendor/github.com/google/cadvisor/info/v1/machine.go delete mode 100644 vendor/github.com/google/cadvisor/info/v1/metric.go delete mode 100644 vendor/github.com/google/cadvisor/info/v2/container.go delete mode 100644 vendor/github.com/google/cadvisor/info/v2/conversion.go delete mode 100644 vendor/github.com/google/cadvisor/info/v2/machine.go delete mode 100644 vendor/github.com/google/cadvisor/machine/info.go delete mode 100644 vendor/github.com/google/cadvisor/machine/machine.go delete mode 100644 vendor/github.com/google/cadvisor/machine/operatingsystem_unix.go delete mode 100644 vendor/github.com/google/cadvisor/machine/operatingsystem_windows.go delete mode 100644 vendor/github.com/google/cadvisor/manager/container.go delete mode 100644 vendor/github.com/google/cadvisor/manager/manager.go delete mode 100644 vendor/github.com/google/cadvisor/nvm/machine_libipmctl.go delete mode 100644 vendor/github.com/google/cadvisor/nvm/machine_no_libipmctl.go delete mode 100644 vendor/github.com/google/cadvisor/perf/collector_libpfm.go delete mode 100644 vendor/github.com/google/cadvisor/perf/collector_no_libpfm.go delete mode 100644 vendor/github.com/google/cadvisor/perf/config.go delete mode 100644 vendor/github.com/google/cadvisor/perf/manager_libpfm.go delete mode 100644 vendor/github.com/google/cadvisor/perf/manager_no_libpfm.go delete mode 100644 vendor/github.com/google/cadvisor/perf/types_libpfm.go delete mode 100644 vendor/github.com/google/cadvisor/perf/uncore_libpfm.go delete mode 100644 vendor/github.com/google/cadvisor/resctrl/factory.go delete mode 100644 vendor/github.com/google/cadvisor/stats/noop.go delete mode 100644 vendor/github.com/google/cadvisor/stats/types.go delete mode 100644 vendor/github.com/google/cadvisor/storage/common_flags.go delete mode 100644 vendor/github.com/google/cadvisor/storage/storage.go delete mode 100644 vendor/github.com/google/cadvisor/summary/buffer.go delete mode 100644 vendor/github.com/google/cadvisor/summary/percentiles.go delete mode 100644 vendor/github.com/google/cadvisor/summary/summary.go delete mode 100644 vendor/github.com/google/cadvisor/utils/cloudinfo/cloudinfo.go delete mode 100644 vendor/github.com/google/cadvisor/utils/cpuload/cpuload.go delete mode 100644 vendor/github.com/google/cadvisor/utils/cpuload/netlink/conn.go delete mode 100644 vendor/github.com/google/cadvisor/utils/cpuload/netlink/netlink.go delete mode 100644 vendor/github.com/google/cadvisor/utils/cpuload/netlink/reader.go delete mode 100644 vendor/github.com/google/cadvisor/utils/oomparser/oomparser.go delete mode 100644 vendor/github.com/google/cadvisor/utils/path.go delete mode 100644 vendor/github.com/google/cadvisor/utils/sysfs/sysfs.go delete mode 100644 vendor/github.com/google/cadvisor/utils/sysfs/sysfs_notx86.go delete mode 100644 vendor/github.com/google/cadvisor/utils/sysfs/sysfs_x86.go delete mode 100644 vendor/github.com/google/cadvisor/utils/sysinfo/sysinfo.go delete mode 100644 vendor/github.com/google/cadvisor/utils/timed_store.go delete mode 100644 vendor/github.com/google/cadvisor/utils/utils.go delete mode 100644 vendor/github.com/google/cadvisor/version/version.go delete mode 100644 vendor/github.com/google/cadvisor/watcher/watcher.go create mode 100644 vendor/github.com/google/cel-go/cel/prompt.go create mode 100644 vendor/github.com/google/cel-go/cel/templates/authoring.tmpl create mode 100644 vendor/github.com/google/cel-go/common/env/BUILD.bazel create mode 100644 vendor/github.com/google/cel-go/common/env/env.go create mode 100644 vendor/github.com/google/cel-go/common/types/format.go create mode 100644 vendor/github.com/google/cel-go/ext/extension_option_factory.go create mode 100644 vendor/github.com/google/cel-go/ext/formatting_v2.go create mode 100644 vendor/github.com/google/cel-go/ext/regex.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/equate.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/ignore.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/sort.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/struct_filter.go delete mode 100644 vendor/github.com/google/go-cmp/cmp/cmpopts/xform.go delete mode 100644 vendor/github.com/karrick/godirwalk/.gitignore delete mode 100644 vendor/github.com/karrick/godirwalk/LICENSE delete mode 100644 vendor/github.com/karrick/godirwalk/README.md delete mode 100644 vendor/github.com/karrick/godirwalk/azure-pipelines.yml delete mode 100644 vendor/github.com/karrick/godirwalk/bench.sh delete mode 100644 vendor/github.com/karrick/godirwalk/debug_development.go delete mode 100644 vendor/github.com/karrick/godirwalk/debug_release.go delete mode 100644 vendor/github.com/karrick/godirwalk/dirent.go delete mode 100644 vendor/github.com/karrick/godirwalk/doc.go delete mode 100644 vendor/github.com/karrick/godirwalk/inoWithFileno.go delete mode 100644 vendor/github.com/karrick/godirwalk/inoWithIno.go delete mode 100644 vendor/github.com/karrick/godirwalk/modeType.go delete mode 100644 vendor/github.com/karrick/godirwalk/modeTypeWithType.go delete mode 100644 vendor/github.com/karrick/godirwalk/modeTypeWithoutType.go delete mode 100644 vendor/github.com/karrick/godirwalk/nameWithNamlen.go delete mode 100644 vendor/github.com/karrick/godirwalk/nameWithoutNamlen.go delete mode 100644 vendor/github.com/karrick/godirwalk/readdir.go delete mode 100644 vendor/github.com/karrick/godirwalk/readdir_unix.go delete mode 100644 vendor/github.com/karrick/godirwalk/readdir_windows.go delete mode 100644 vendor/github.com/karrick/godirwalk/reclenFromNamlen.go delete mode 100644 vendor/github.com/karrick/godirwalk/reclenFromReclen.go delete mode 100644 vendor/github.com/karrick/godirwalk/scandir_unix.go delete mode 100644 vendor/github.com/karrick/godirwalk/scandir_windows.go delete mode 100644 vendor/github.com/karrick/godirwalk/scanner.go delete mode 100644 vendor/github.com/karrick/godirwalk/walk.go delete mode 100644 vendor/github.com/mistifyio/go-zfs/.gitignore delete mode 100644 vendor/github.com/mistifyio/go-zfs/.travis.yml delete mode 100644 vendor/github.com/mistifyio/go-zfs/CONTRIBUTING.md delete mode 100644 vendor/github.com/mistifyio/go-zfs/LICENSE delete mode 100644 vendor/github.com/mistifyio/go-zfs/README.md delete mode 100644 vendor/github.com/mistifyio/go-zfs/Vagrantfile delete mode 100644 vendor/github.com/mistifyio/go-zfs/error.go delete mode 100644 vendor/github.com/mistifyio/go-zfs/utils.go delete mode 100644 vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go delete mode 100644 vendor/github.com/mistifyio/go-zfs/utils_solaris.go delete mode 100644 vendor/github.com/mistifyio/go-zfs/zfs.go delete mode 100644 vendor/github.com/mistifyio/go-zfs/zpool.go delete mode 100644 vendor/github.com/moby/sys/userns/LICENSE delete mode 100644 vendor/github.com/moby/sys/userns/userns.go delete mode 100644 vendor/github.com/moby/sys/userns/userns_linux.go delete mode 100644 vendor/github.com/moby/sys/userns/userns_linux_fuzzer.go delete mode 100644 vendor/github.com/moby/sys/userns/userns_unsupported.go delete mode 100644 vendor/github.com/opencontainers/cgroups/CODEOWNERS delete mode 100644 vendor/github.com/opencontainers/cgroups/CONTRIBUTING.md delete mode 100644 vendor/github.com/opencontainers/cgroups/GOVERNANCE.md delete mode 100644 vendor/github.com/opencontainers/cgroups/LICENSE delete mode 100644 vendor/github.com/opencontainers/cgroups/MAINTAINERS delete mode 100644 vendor/github.com/opencontainers/cgroups/MAINTAINERS_GUIDE.md delete mode 100644 vendor/github.com/opencontainers/cgroups/README.md delete mode 100644 vendor/github.com/opencontainers/cgroups/RELEASES.md delete mode 100644 vendor/github.com/opencontainers/cgroups/cgroups.go delete mode 100644 vendor/github.com/opencontainers/cgroups/config_blkio_device.go delete mode 100644 vendor/github.com/opencontainers/cgroups/config_hugepages.go delete mode 100644 vendor/github.com/opencontainers/cgroups/config_ifprio_map.go delete mode 100644 vendor/github.com/opencontainers/cgroups/config_linux.go delete mode 100644 vendor/github.com/opencontainers/cgroups/config_rdma.go delete mode 100644 vendor/github.com/opencontainers/cgroups/config_unsupported.go delete mode 100644 vendor/github.com/opencontainers/cgroups/devices/config/device.go delete mode 100644 vendor/github.com/opencontainers/cgroups/devices/config/mknod_unix.go delete mode 100644 vendor/github.com/opencontainers/cgroups/file.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/blkio.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/cpu.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/cpuacct.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/cpuset.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/devices.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/error.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/freezer.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/fs.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/hugetlb.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/memory.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/name.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/net_cls.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/net_prio.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/paths.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/perf_event.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/pids.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs/rdma.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/cpu.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/cpuset.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/create.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/defaultpath.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/freezer.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/fs2.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/hugetlb.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/io.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/memory.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/misc.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/pids.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fs2/psi.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fscommon/rdma.go delete mode 100644 vendor/github.com/opencontainers/cgroups/fscommon/utils.go delete mode 100644 vendor/github.com/opencontainers/cgroups/getallpids.go delete mode 100644 vendor/github.com/opencontainers/cgroups/internal/path/path.go delete mode 100644 vendor/github.com/opencontainers/cgroups/manager/new.go delete mode 100644 vendor/github.com/opencontainers/cgroups/stats.go delete mode 100644 vendor/github.com/opencontainers/cgroups/systemd/common.go delete mode 100644 vendor/github.com/opencontainers/cgroups/systemd/cpuset.go delete mode 100644 vendor/github.com/opencontainers/cgroups/systemd/dbus.go delete mode 100644 vendor/github.com/opencontainers/cgroups/systemd/devices.go delete mode 100644 vendor/github.com/opencontainers/cgroups/systemd/user.go delete mode 100644 vendor/github.com/opencontainers/cgroups/systemd/v1.go delete mode 100644 vendor/github.com/opencontainers/cgroups/systemd/v2.go delete mode 100644 vendor/github.com/opencontainers/cgroups/utils.go delete mode 100644 vendor/github.com/opencontainers/cgroups/v1_utils.go delete mode 100644 vendor/github.com/opencontainers/image-spec/LICENSE delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/v1/annotations.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/v1/config.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/v1/descriptor.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/v1/index.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/v1/layout.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/v1/manifest.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/v1/mediatype.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/version.go delete mode 100644 vendor/github.com/opencontainers/image-spec/specs-go/versioned.go delete mode 100644 vendor/github.com/opencontainers/runtime-spec/LICENSE delete mode 100644 vendor/github.com/opencontainers/runtime-spec/specs-go/config.go delete mode 100644 vendor/github.com/opencontainers/runtime-spec/specs-go/state.go delete mode 100644 vendor/github.com/opencontainers/runtime-spec/specs-go/version.go delete mode 100644 vendor/github.com/sirupsen/logrus/.gitignore delete mode 100644 vendor/github.com/sirupsen/logrus/.golangci.yml delete mode 100644 vendor/github.com/sirupsen/logrus/.travis.yml delete mode 100644 vendor/github.com/sirupsen/logrus/CHANGELOG.md delete mode 100644 vendor/github.com/sirupsen/logrus/LICENSE delete mode 100644 vendor/github.com/sirupsen/logrus/README.md delete mode 100644 vendor/github.com/sirupsen/logrus/alt_exit.go delete mode 100644 vendor/github.com/sirupsen/logrus/appveyor.yml delete mode 100644 vendor/github.com/sirupsen/logrus/buffer_pool.go delete mode 100644 vendor/github.com/sirupsen/logrus/doc.go delete mode 100644 vendor/github.com/sirupsen/logrus/entry.go delete mode 100644 vendor/github.com/sirupsen/logrus/exported.go delete mode 100644 vendor/github.com/sirupsen/logrus/formatter.go delete mode 100644 vendor/github.com/sirupsen/logrus/hooks.go delete mode 100644 vendor/github.com/sirupsen/logrus/json_formatter.go delete mode 100644 vendor/github.com/sirupsen/logrus/logger.go delete mode 100644 vendor/github.com/sirupsen/logrus/logrus.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_appengine.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_bsd.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_js.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_no_terminal.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_notappengine.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_solaris.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_unix.go delete mode 100644 vendor/github.com/sirupsen/logrus/terminal_check_windows.go delete mode 100644 vendor/github.com/sirupsen/logrus/text_formatter.go delete mode 100644 vendor/github.com/sirupsen/logrus/writer.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/LICENSE delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/config.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/doc.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptor.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/interceptorinfo.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal/parse.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/metadata_supplier.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/semconv.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/stats_handler.go delete mode 100644 vendor/go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/version.go create mode 100644 vendor/google.golang.org/grpc/balancer/endpointsharding/endpointsharding.go create mode 100644 vendor/google.golang.org/grpc/balancer/subconn.go delete mode 100644 vendor/google.golang.org/grpc/internal/grpcsync/oncefunc.go create mode 100644 vendor/google.golang.org/grpc/internal/proxyattributes/proxyattributes.go create mode 100644 vendor/google.golang.org/grpc/internal/resolver/delegatingresolver/delegatingresolver.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/client_stream.go create mode 100644 vendor/google.golang.org/grpc/internal/transport/server_stream.go create mode 100644 vendor/google.golang.org/grpc/stats/metrics.go delete mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/metrics/OWNERS delete mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/metrics/metrics.go delete mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/responsewriter/fake.go delete mode 100644 vendor/k8s.io/apiserver/pkg/endpoints/responsewriter/wrapper.go delete mode 100644 vendor/k8s.io/apiserver/pkg/server/healthz/doc.go delete mode 100644 vendor/k8s.io/apiserver/pkg/server/healthz/healthz.go delete mode 100644 vendor/k8s.io/apiserver/pkg/server/httplog/doc.go delete mode 100644 vendor/k8s.io/apiserver/pkg/server/httplog/httplog.go delete mode 100644 vendor/k8s.io/apiserver/pkg/server/routine/routine.go delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/OWNERS delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/api_object_versioner.go delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/continue.go delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/doc.go delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/errors.go delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/interfaces.go delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/selection_predicate.go delete mode 100644 vendor/k8s.io/apiserver/pkg/storage/util.go delete mode 100644 vendor/k8s.io/client-go/dynamic/dynamicinformer/informer.go delete mode 100644 vendor/k8s.io/client-go/dynamic/dynamicinformer/interface.go delete mode 100644 vendor/k8s.io/client-go/dynamic/dynamiclister/interface.go delete mode 100644 vendor/k8s.io/client-go/dynamic/dynamiclister/lister.go delete mode 100644 vendor/k8s.io/client-go/dynamic/dynamiclister/shim.go delete mode 100644 vendor/k8s.io/client-go/tools/events/OWNERS delete mode 100644 vendor/k8s.io/client-go/tools/events/doc.go delete mode 100644 vendor/k8s.io/client-go/tools/events/event_broadcaster.go delete mode 100644 vendor/k8s.io/client-go/tools/events/event_recorder.go delete mode 100644 vendor/k8s.io/client-go/tools/events/fake.go delete mode 100644 vendor/k8s.io/client-go/tools/events/helper.go delete mode 100644 vendor/k8s.io/client-go/tools/events/interfaces.go delete mode 100644 vendor/k8s.io/cloud-provider/volume/constants.go delete mode 100644 vendor/k8s.io/cloud-provider/volume/helpers/rounding.go delete mode 100644 vendor/k8s.io/cloud-provider/volume/helpers/zones.go delete mode 100644 vendor/k8s.io/component-base/config/OWNERS delete mode 100644 vendor/k8s.io/component-base/config/doc.go delete mode 100644 vendor/k8s.io/component-base/config/types.go delete mode 100644 vendor/k8s.io/component-base/config/v1alpha1/conversion.go delete mode 100644 vendor/k8s.io/component-base/config/v1alpha1/defaults.go delete mode 100644 vendor/k8s.io/component-base/config/v1alpha1/doc.go delete mode 100644 vendor/k8s.io/component-base/config/v1alpha1/register.go delete mode 100644 vendor/k8s.io/component-base/config/v1alpha1/types.go delete mode 100644 vendor/k8s.io/component-base/config/v1alpha1/zz_generated.conversion.go delete mode 100644 vendor/k8s.io/component-base/config/v1alpha1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/component-base/config/validation/validation.go delete mode 100644 vendor/k8s.io/component-base/config/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/component-base/logs/logreduction/logreduction.go delete mode 100644 vendor/k8s.io/component-base/metrics/prometheus/slis/metrics.go delete mode 100644 vendor/k8s.io/component-base/metrics/prometheus/slis/registry.go delete mode 100644 vendor/k8s.io/component-base/metrics/prometheus/slis/routes.go delete mode 100644 vendor/k8s.io/component-helpers/node/topology/helpers.go delete mode 100644 vendor/k8s.io/component-helpers/storage/ephemeral/ephemeral.go delete mode 100644 vendor/k8s.io/component-helpers/storage/volume/helpers.go delete mode 100644 vendor/k8s.io/component-helpers/storage/volume/pv_helpers.go delete mode 100644 vendor/k8s.io/cri-api/LICENSE delete mode 100644 vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.pb.go delete mode 100644 vendor/k8s.io/cri-api/pkg/apis/runtime/v1/api.proto delete mode 100644 vendor/k8s.io/cri-api/pkg/apis/runtime/v1/constants.go delete mode 100644 vendor/k8s.io/cri-api/pkg/apis/services.go delete mode 100644 vendor/k8s.io/cri-client/LICENSE delete mode 100644 vendor/k8s.io/cri-client/pkg/doc.go delete mode 100644 vendor/k8s.io/cri-client/pkg/internal/log.go delete mode 100644 vendor/k8s.io/cri-client/pkg/logs/logs.go delete mode 100644 vendor/k8s.io/cri-client/pkg/logs/logs_other.go delete mode 100644 vendor/k8s.io/cri-client/pkg/logs/logs_windows.go delete mode 100644 vendor/k8s.io/cri-client/pkg/logs/tail.go delete mode 100644 vendor/k8s.io/cri-client/pkg/remote_image.go delete mode 100644 vendor/k8s.io/cri-client/pkg/remote_runtime.go delete mode 100644 vendor/k8s.io/cri-client/pkg/util/util_unix.go delete mode 100644 vendor/k8s.io/cri-client/pkg/util/util_unsupported.go delete mode 100644 vendor/k8s.io/cri-client/pkg/util/util_windows.go delete mode 100644 vendor/k8s.io/cri-client/pkg/utils.go delete mode 100644 vendor/k8s.io/csi-translation-lib/CONTRIBUTING.md delete mode 100644 vendor/k8s.io/csi-translation-lib/LICENSE delete mode 100644 vendor/k8s.io/csi-translation-lib/OWNERS delete mode 100644 vendor/k8s.io/csi-translation-lib/README.md delete mode 100644 vendor/k8s.io/csi-translation-lib/SECURITY_CONTACTS delete mode 100644 vendor/k8s.io/csi-translation-lib/code-of-conduct.md delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/aws_ebs.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/azure_disk.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/azure_file.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/const.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/gce_pd.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/in_tree_volume.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/openstack_cinder.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/portworx.go delete mode 100644 vendor/k8s.io/csi-translation-lib/plugins/vsphere_volume.go delete mode 100644 vendor/k8s.io/csi-translation-lib/translate.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/LICENSE delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/api/conversion.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/api/doc.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/api/types.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/api/uniquestring.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/api/zz_generated.conversion.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/cel/cache.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/cel/compile.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/internal/queue/fifo.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/resourceclaim/devicetoleration.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/resourceclaim/pod.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/resourceclaim/resourceclaim.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/resourceslice/tracker/tracker.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/structured/allocator.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/structured/doc.go delete mode 100644 vendor/k8s.io/dynamic-resource-allocation/structured/pools.go create mode 100644 vendor/k8s.io/kube-openapi/pkg/validation/strfmt/kubernetes-extensions.go delete mode 100644 vendor/k8s.io/kube-scheduler/LICENSE delete mode 100644 vendor/k8s.io/kube-scheduler/config/v1/doc.go delete mode 100644 vendor/k8s.io/kube-scheduler/config/v1/register.go delete mode 100644 vendor/k8s.io/kube-scheduler/config/v1/types.go delete mode 100644 vendor/k8s.io/kube-scheduler/config/v1/types_pluginargs.go delete mode 100644 vendor/k8s.io/kube-scheduler/config/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kube-scheduler/extender/v1/doc.go delete mode 100644 vendor/k8s.io/kube-scheduler/extender/v1/types.go delete mode 100644 vendor/k8s.io/kube-scheduler/extender/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1/api.pb.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1/api.proto delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1/constants.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1alpha4/api.pb.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1alpha4/api.proto delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1alpha4/conversion.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1alpha4/doc.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1alpha4/types.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1alpha4/zz_generated.conversion.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1beta1/api.pb.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1beta1/api.proto delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/dra/v1beta1/types.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/pluginregistration/v1/api.pb.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/pluginregistration/v1/api.proto delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/pluginregistration/v1/constants.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/podresources/v1/api.pb.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/podresources/v1/api.proto delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/podresources/v1alpha1/api.pb.go delete mode 100644 vendor/k8s.io/kubelet/pkg/apis/podresources/v1alpha1/api.proto create mode 100644 vendor/k8s.io/kubernetes/pkg/apis/certificates/OWNERS rename vendor/k8s.io/kubernetes/pkg/apis/{scheduling => certificates}/doc.go (85%) create mode 100644 vendor/k8s.io/kubernetes/pkg/apis/certificates/helpers.go rename vendor/k8s.io/kubernetes/pkg/apis/{scheduling => certificates}/register.go (78%) create mode 100644 vendor/k8s.io/kubernetes/pkg/apis/certificates/types.go create mode 100644 vendor/k8s.io/kubernetes/pkg/apis/certificates/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/apis/core/v1/helper/qos/qos.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/apis/scheduling/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/apis/scheduling/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/credentialprovider/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/credentialprovider/config.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/credentialprovider/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/credentialprovider/keyring.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/credentialprovider/provider.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/helpers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/register.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/config/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/.mockery.yaml delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/client.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/constants.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/server_v1.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/server_v1alpha1.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/apis/podresources/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/.mockery.yaml delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/cadvisor_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/helpers_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cadvisor/util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/checkpointmanager/README.md delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checkpoint_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum/checksum.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors/errors.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/.mockery.yaml delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/admission/errors.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_manager_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_v1_manager_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cgroup_v2_manager_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_stub.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/container_manager_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/containermap/container_map.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_assignment.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/alignment.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/topology.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint/checkpoint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/endpoint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/api.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/handler.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/server.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/stub.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/pod_devices.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugin.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugins_store.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/registration.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpoint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpointer.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_internal_container_lifecycle.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_pod_container_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_stub.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates/updates.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/numa_info.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_best_effort.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_none.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_options.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_restricted.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/common.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/defaults.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/flags.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/config/sources.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/.mockery.yaml delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache_fake.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/eviction/api/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/metrics/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/actual_state_of_world.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/desired_state_of_world.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/qos/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/qos/helpers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/qos/policy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/status/.mockery.yaml delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/types/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_status.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/types/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/node_startup_latency_tracker.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/nodelease.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/store/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/store/filestore.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/store/store.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/swap/swap_util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/winstats/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/probe/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/probe/http/http.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/probe/http/request.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/probe/probe.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/probe/util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/register.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/scheme/scheme.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types_pluginargs.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/conversion.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/register.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.defaults.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/comparer.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/debugger.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/dumper.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/node_tree.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/heap/heap.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/backoff_queue.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/nominator.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/testing.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/extender.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/events.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/extender.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/listers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/parallelism.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/README.md delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder/default_binder.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/normalize_score.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/shape_score.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/spread.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/taint.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/filtering.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename/node_name.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports/node_ports.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable/node_unschedulable.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/common.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/scoring.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort/priority_sort.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates/scheduling_gates.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration/taint_toleration.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/fake_binder.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics/metrics.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/scorer.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/test_utils.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/volume_zone.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/instrumented_plugins.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/registry.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/util/pod_resources.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/util/queue/fifo.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/security/apparmor/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/security/apparmor/helpers.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go rename vendor/k8s.io/kubernetes/pkg/{probe => securitycontext}/OWNERS (100%) delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/filesystem/defaultfs.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/filesystem/filesystem.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/kernel/OWNERS delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/kernel/version.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/oom/doc.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/oom/oom.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/oom/oom_fake.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/pod/pod.go delete mode 100644 vendor/k8s.io/kubernetes/pkg/util/slice/slice.go delete mode 100644 vendor/k8s.io/kubernetes/test/e2e/framework/pod/resize.go create mode 100644 vendor/k8s.io/kubernetes/test/e2e/storage/utils/file.go delete mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/service.yaml delete mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/statefulset.yaml delete mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/service.yaml delete mode 100644 vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/golang/LICENSE delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/golang/PATENTS delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/golang/expansion/expand.go delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/libcontainer/LICENSE delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/libcontainer/NOTICE delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_linux.go delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go delete mode 100644 vendor/k8s.io/kubernetes/third_party/forked/libcontainer/utils/utils.go delete mode 100644 vendor/k8s.io/utils/cpuset/OWNERS delete mode 100644 vendor/k8s.io/utils/cpuset/cpuset.go delete mode 100644 vendor/k8s.io/utils/inotify/LICENSE delete mode 100644 vendor/k8s.io/utils/inotify/PATENTS delete mode 100644 vendor/k8s.io/utils/inotify/README.md delete mode 100644 vendor/k8s.io/utils/inotify/inotify.go delete mode 100644 vendor/k8s.io/utils/inotify/inotify_linux.go delete mode 100644 vendor/k8s.io/utils/inotify/inotify_others.go rename vendor/{github.com/euank/go-kmsg-parser => sigs.k8s.io/structured-merge-diff/v6}/LICENSE (100%) create mode 100644 vendor/sigs.k8s.io/structured-merge-diff/v6/schema/doc.go create mode 100644 vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go create mode 100644 vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go create mode 100644 vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go diff --git a/go.mod b/go.mod index 6d7aa46b1..4854f369f 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( go.uber.org/mock v0.6.0 golang.org/x/net v0.47.0 golang.org/x/sync v0.19.0 - google.golang.org/grpc v1.68.1 + google.golang.org/grpc v1.72.1 google.golang.org/protobuf v1.36.10 k8s.io/api v0.33.4 k8s.io/apimachinery v0.33.4 @@ -37,8 +37,8 @@ require ( k8s.io/client-go v0.33.4 k8s.io/component-base v0.33.4 k8s.io/klog/v2 v2.130.1 - k8s.io/kubernetes v1.33.7 - k8s.io/mount-utils v0.34.2 + k8s.io/kubernetes v1.34.3 + k8s.io/mount-utils v0.34.3 k8s.io/pod-security-admission v0.31.1 k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 sigs.k8s.io/cloud-provider-azure v1.29.1-0.20250701013630-7cd6c31d3f88 @@ -48,7 +48,7 @@ require ( ) require ( - cel.dev/expr v0.19.1 // indirect + cel.dev/expr v0.24.0 // indirect cyphar.com/go-pathrs v0.2.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.2.0 // indirect @@ -67,67 +67,48 @@ require ( github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Azure/msi-dataplane v0.4.3 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 // indirect - github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab // indirect github.com/Masterminds/semver/v3 v3.4.0 // indirect - github.com/Microsoft/go-winio v0.6.2 // indirect github.com/antlr4-go/antlr/v4 v4.13.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/containerd/containerd/api v1.8.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/ttrpc v1.2.6 // indirect - github.com/containerd/typeurl/v2 v2.2.2 // indirect - github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cyphar/filepath-securejoin v0.6.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.1 // indirect - github.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect - github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.2 // indirect - github.com/google/cadvisor v0.52.1 // indirect - github.com/google/cel-go v0.23.2 // indirect - github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/cel-go v0.26.0 // indirect + github.com/google/gnostic-models v0.7.0 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect - github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/karrick/godirwalk v1.17.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect github.com/moby/spdystream v0.5.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect - github.com/moby/sys/userns v0.1.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/opencontainers/cgroups v0.0.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opencontainers/selinux v1.13.0 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect @@ -136,23 +117,21 @@ require ( github.com/prometheus/common v0.65.0 // indirect github.com/prometheus/procfs v0.16.1 // indirect github.com/samber/lo v1.51.0 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cobra v1.9.1 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/stoewer/go-strcase v1.3.0 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.59.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.4.0 // indirect + go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/crypto v0.45.0 // indirect @@ -164,8 +143,8 @@ require ( golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.12.0 // indirect golang.org/x/tools v0.38.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect @@ -173,19 +152,15 @@ require ( k8s.io/cloud-provider v0.33.4 // indirect k8s.io/component-helpers v0.33.4 // indirect k8s.io/controller-manager v0.33.4 // indirect - k8s.io/cri-api v0.33.4 // indirect - k8s.io/cri-client v0.0.0 // indirect - k8s.io/csi-translation-lib v0.0.0 // indirect - k8s.io/dynamic-resource-allocation v0.0.0 // indirect - k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect - k8s.io/kube-scheduler v0.0.0 // indirect + k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect k8s.io/kubectl v0.31.1 // indirect k8s.io/kubelet v0.33.4 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect sigs.k8s.io/cloud-provider-azure/pkg/azclient/cache v0.7.3 // indirect - sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect ) replace ( diff --git a/go.sum b/go.sum index 82063aad0..18b248181 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -cel.dev/expr v0.19.1 h1:NciYrtDRIR0lNCnH1LFJegdjspNx9fI59O7TWcua/W4= -cel.dev/expr v0.19.1/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= +cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8= cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc= github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= @@ -70,12 +70,8 @@ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJ github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0 h1:XRzhVemXdgvJqCH0sFfrBUTnUJSBrBf7++ypk+twtRs= github.com/AzureAD/microsoft-authentication-library-for-go v1.6.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk= -github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab h1:UKkYhof1njT1/xq4SEg5z+VpTgjmNeHwPGRQl7takDI= -github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= 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= -github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= @@ -90,20 +86,6 @@ github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UF github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/container-storage-interface/spec v1.12.0 h1:zrFOEqpR5AghNaaDG4qyedwPBqU2fU0dWjLQMP/azK0= github.com/container-storage-interface/spec v1.12.0/go.mod h1:txsm+MA2B2WDa5kW69jNbqPnvTtfvZma7T/zsAZ9qX8= -github.com/containerd/containerd/api v1.8.0 h1:hVTNJKR8fMc/2Tiw60ZRijntNMd1U+JVMyTRdsD2bS0= -github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= -github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= -github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= -github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= -github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= -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/ttrpc v1.2.6 h1:zG+Kn5EZ6MUYCS1t2Hmt2J4tMVaLSFEJVOraDQwNPC4= -github.com/containerd/ttrpc v1.2.6/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= -github.com/containerd/typeurl/v2 v2.2.2 h1:3jN/k2ysKuPCsln5Qv8bzR9cxal8XjkxPogJfSNO31k= -github.com/containerd/typeurl/v2 v2.2.2/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= -github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= -github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is= github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc= @@ -117,22 +99,14 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v26.1.4+incompatible h1:vuTpXDuoga+Z38m1OZHzl7NKisKWaWlhjQk7IDPSLsU= -github.com/docker/docker v26.1.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= -github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= -github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= -github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/euank/go-kmsg-parser v2.0.0+incompatible h1:cHD53+PLQuuQyLZeriD1V/esuG4MuU0Pjs5y6iknohY= -github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= -github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= -github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= @@ -160,9 +134,6 @@ github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1v github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= -github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -175,12 +146,10 @@ github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeD github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/google/cadvisor v0.52.1 h1:sC8SZ6jio9ds+P2dk51bgbeYeufxo55n0X3tmrpA9as= -github.com/google/cadvisor v0.52.1/go.mod h1:OAhPcx1nOm5YwMh/JhpUOMKyv1YKLRtS9KgzWPndHmA= -github.com/google/cel-go v0.23.2 h1:UdEe3CvQh3Nv+E/j9r1Y//WO0K0cSyD7/y0bzyLIMI4= -github.com/google/cel-go v0.23.2/go.mod h1:52Pb6QsDbC5kvgxvZhiL9QX1oZEkcUF/ZqaPx1J5Wwo= -github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= -github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/cel-go v0.26.0 h1:DPGjXackMpJWH680oGY4lZhYjIameYmR+/6RBdDGmaI= +github.com/google/cel-go v0.26.0/go.mod h1:A9O8OU9rdvrK5MQyrqfIxo1a0u4g3sF8KB6PUIaryMM= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= 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= @@ -194,10 +163,10 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 h1:QGLs/O40yoNK9vmy4rhUGBVyMf1lISBGtXRpsu/Qu/o= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0/go.mod h1:hM2alZsMUni80N33RBe6J0e423LB+odMj7d3EMP9l20= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 h1:pRhl55Yx1eC7BZ1N+BBWwnKaMyD8uC+34TLdndZMAKk= -github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0/go.mod h1:XKMd7iuf/RGPSMJ/U4HP0zS2Z9Fh8Ps9a+6X26m/tmI= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 h1:TmHmbvxPmaegwhDubVz0lICL0J5Ka2vwTzhoePEXsGE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0/go.mod h1:qztMSjm835F2bXf+5HKAPIS5qsmQDqZna/PgVt4rWtI= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3/go.mod h1:ndYquD05frm2vACXE1nsccT4oJzjhw2arTS2cpUD1PI= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -206,8 +175,6 @@ github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= -github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXwkPPMeUgOK1k= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= @@ -228,21 +195,16 @@ github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= -github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk= -github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= -github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= -github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= 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/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= -github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= @@ -251,14 +213,8 @@ github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= -github.com/opencontainers/cgroups v0.0.1 h1:MXjMkkFpKv6kpuirUa4USFBas573sSAY082B4CiHEVA= -github.com/opencontainers/cgroups v0.0.1/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= -github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/opencontainers/runtime-spec v1.2.0 h1:z97+pHb3uELt/yiAWD691HNHQIF07bE7dzrbT927iTk= -github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= github.com/opencontainers/selinux v1.13.0 h1:Zza88GWezyT7RLql12URvoxsbLfjFx988+LGaWfbL84= github.com/opencontainers/selinux v1.13.0/go.mod h1:XxWTed+A/s5NNq4GmYScVy+9jzXhGBVEOAyucdRUY8s= github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw= @@ -284,8 +240,6 @@ github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWN github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/samber/lo v1.51.0 h1:kysRYLbHy/MB7kQZf5DSN50JHmMsNEdeY24VzJFu7wI= github.com/samber/lo v1.51.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= @@ -298,7 +252,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE 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.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= @@ -320,16 +273,14 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= go.opentelemetry.io/otel/exporters/prometheus v0.59.0 h1:HHf+wKS6o5++XZhS98wvILrLVgHxjA/AMjqHKes+uzo= go.opentelemetry.io/otel/exporters/prometheus v0.59.0/go.mod h1:R8GpRXTZrqvXHDEGVH5bF6+JqAZcK8PjJcZ5nGhEWiE= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= @@ -340,8 +291,8 @@ go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFh go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.4.0 h1:TA9WRvW6zMwP+Ssb6fLoUIuirti1gGbP28GcKG1jgeg= -go.opentelemetry.io/proto/otlp v1.4.0/go.mod h1:PPBWZIP98o2ElSqI35IHfu7hIhSwvc5N38Jw8pXuGFY= +go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= +go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y= @@ -397,7 +348,6 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -435,12 +385,12 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 h1:CkkIfIt50+lT6NHAVoRYEyAvQGFM7xEwXUUywFvEb3Q= -google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576/go.mod h1:1R3kvZ1dtP3+4p4d3G8uJ8rFk/fWlScl38vanWACI08= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 h1:8ZmaLZE4XWrtU3MyClkYqqtl6Oegr3235h7jxsDyqCY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= -google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0= -google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950= +google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I= +google.golang.org/grpc v1.72.1 h1:HR03wO6eyZ7lknl75XlxABNVLLFc2PAb6mHlYh756mA= +google.golang.org/grpc v1.72.1/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -475,28 +425,20 @@ k8s.io/component-helpers v0.33.4 h1:DYHQPxWB3XIk7hwAQ4YczUelJ37PcUHfnLeee0qFqV8= k8s.io/component-helpers v0.33.4/go.mod h1:kRgidIgCKFqOW/wy7D8IL3YOT3iaIRZu6FcTEyRr7WU= k8s.io/controller-manager v0.33.4 h1:HmlzmmNPu8H+cKEpAIRz0ptqpveKcj7KrCx9G+HXRAg= k8s.io/controller-manager v0.33.4/go.mod h1:CpO8RarLcs7zh0sE4pqz88quF3xU3Dc4ZDfshnB8hw4= -k8s.io/cri-api v0.33.4 h1:P49b1XSTqIKu79pTV6Ig+tMM20NupmZ8AVZ9rWSz1VQ= -k8s.io/cri-api v0.33.4/go.mod h1:OLQvT45OpIA+tv91ZrpuFIGY+Y2Ho23poS7n115Aocs= -k8s.io/cri-client v0.33.4 h1:WPZjjU7sA6i5pululXbatDeIYvNDFMtX5qK/YkfFG30= -k8s.io/cri-client v0.33.4/go.mod h1:/v6lx4bfth4SYFdC2N1nPERn8+eHGNC5924IPL8VsCw= k8s.io/csi-translation-lib v0.33.4 h1:LmiElxqQwISv0c2mdL3rswmPIIN6Qh+4Lv0bdKTTFoM= k8s.io/csi-translation-lib v0.33.4/go.mod h1:A4Kn6gTWX5EkxbHgtiDitNjDVvk2plie7lo8Hpa19Bg= -k8s.io/dynamic-resource-allocation v0.33.4 h1:CzGpfPS14cj7W7FIaCcOG0S01UDmi52AxtNjU0YGSRM= -k8s.io/dynamic-resource-allocation v0.33.4/go.mod h1:3dtKRcjPY6XRhgOpsToIy/o2VffPdf647Iaro10rs9k= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= -k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= -k8s.io/kube-scheduler v0.33.4 h1:RNlrqBL0lyILGCsD78xcuaDqAIfccL2j5g+eVJntWL8= -k8s.io/kube-scheduler v0.33.4/go.mod h1:bNYhEZ0GAj5wbnWa8B3Bu1AqlE9nLacFoezpEtSSqik= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b h1:MloQ9/bdJyIu9lb1PzujOPolHyvO06MXG5TUIj2mNAA= +k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts= k8s.io/kubectl v0.33.4 h1:nXEI6Vi+oB9hXxoAHyHisXolm/l1qutK3oZQMak4N98= k8s.io/kubectl v0.33.4/go.mod h1:Xe7P9X4DfILvKmlBsVqUtzktkI56lEj22SJW7cFy6nE= k8s.io/kubelet v0.33.4 h1:+sbpLmSq+Y8DF/OQeyw75OpuiF60tvlYcmc/yjN+nl4= k8s.io/kubelet v0.33.4/go.mod h1:wboarviFRQld5rzZUjTliv7x00YVx+YhRd/p1OahX7Y= -k8s.io/kubernetes v1.33.7 h1:Qhp1gwCPSOqt3du6A0uTGrrTcZDtShdSCIR5IZag16Y= -k8s.io/kubernetes v1.33.7/go.mod h1:eJiHC143tnNSvmDkCRwGNKA80yXqBvYC3U8L/i67nAY= -k8s.io/mount-utils v0.34.2 h1:DiesOtAiYccJWKGRlJZhRkjCHvpQ3YmSlQp+zkkvf9Y= -k8s.io/mount-utils v0.34.2/go.mod h1:MIjjYlqJ0ziYQg0MO09kc9S96GIcMkhF/ay9MncF0GA= +k8s.io/kubernetes v1.34.3 h1:0TfljWbhEF5DBks+WFMSrvKfxBLo4vnZuqORjLMiyT4= +k8s.io/kubernetes v1.34.3/go.mod h1:m6pZk6a179pRo2wsTiCPORJ86iOEQmfIzUvtyEF8BwA= +k8s.io/mount-utils v0.34.3 h1:+sk7PVMQhGoNkGnxmxhyjEXpFcTaD6s3a6NXZNhqERc= +k8s.io/mount-utils v0.34.3/go.mod h1:MIjjYlqJ0ziYQg0MO09kc9S96GIcMkhF/ay9MncF0GA= k8s.io/pod-security-admission v0.33.4 h1:adSwY7a/Q4Eoj+uCUfav90xRe6mB8waF0HAZ4gZeWD0= k8s.io/pod-security-admission v0.33.4/go.mod h1:K+4JaqBz5yqE7TXf3g5zEiBLcu9RdW2BjTWydFEror4= k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 h1:hwvWFiBzdWw1FhfY1FooPn3kzWuJ8tmbZBHi4zVsl1Y= @@ -511,13 +453,15 @@ sigs.k8s.io/cloud-provider-azure/pkg/azclient/cache v0.7.3 h1:zTvlSDuS7oTx4dJJ1n sigs.k8s.io/cloud-provider-azure/pkg/azclient/cache v0.7.3/go.mod h1:TFiBWKtV3AE5wgW1jiJtJEwVHDyVDEhBaE8hnI/HnCY= sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.7.2 h1:KwkEnyG9Ej9keeO8RoJBpOaZSIpkYM8d4kzKaIHeehs= sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.7.2/go.mod h1:Gsc4rGVFioD2LW5qLC+qMpnpGqpo64vr4UhBUkMdfFo= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= -sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= +sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/vendor/cel.dev/expr/.bazelversion b/vendor/cel.dev/expr/.bazelversion index 26bc914a3..13c50892b 100644 --- a/vendor/cel.dev/expr/.bazelversion +++ b/vendor/cel.dev/expr/.bazelversion @@ -1,2 +1,2 @@ -7.0.1 +7.3.2 # Keep this pinned version in parity with cel-go diff --git a/vendor/cel.dev/expr/MODULE.bazel b/vendor/cel.dev/expr/MODULE.bazel index 9794266f5..85ac9ff61 100644 --- a/vendor/cel.dev/expr/MODULE.bazel +++ b/vendor/cel.dev/expr/MODULE.bazel @@ -8,26 +8,38 @@ bazel_dep( ) bazel_dep( name = "gazelle", - version = "0.36.0", + version = "0.39.1", repo_name = "bazel_gazelle", ) bazel_dep( name = "googleapis", - version = "0.0.0-20240819-fe8ba054a", + version = "0.0.0-20241220-5e258e33.bcr.1", repo_name = "com_google_googleapis", ) +bazel_dep( + name = "googleapis-cc", + version = "1.0.0", +) +bazel_dep( + name = "googleapis-java", + version = "1.0.0", +) +bazel_dep( + name = "googleapis-go", + version = "1.0.0", +) bazel_dep( name = "protobuf", - version = "26.0", + version = "27.0", repo_name = "com_google_protobuf", ) bazel_dep( name = "rules_cc", - version = "0.0.9", + version = "0.0.17", ) bazel_dep( name = "rules_go", - version = "0.49.0", + version = "0.53.0", repo_name = "io_bazel_rules_go", ) bazel_dep( @@ -36,7 +48,7 @@ bazel_dep( ) bazel_dep( name = "rules_proto", - version = "6.0.0", + version = "7.0.2", ) bazel_dep( name = "rules_python", @@ -50,16 +62,8 @@ python.toolchain( python_version = "3.11", ) -switched_rules = use_extension("@com_google_googleapis//:extensions.bzl", "switched_rules") -switched_rules.use_languages( - cc = True, - go = True, - java = True, -) -use_repo(switched_rules, "com_google_googleapis_imports") - go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk") -go_sdk.download(version = "1.21.1") +go_sdk.download(version = "1.22.0") go_deps = use_extension("@bazel_gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//:go.mod") diff --git a/vendor/cel.dev/expr/README.md b/vendor/cel.dev/expr/README.md index 7930c0b75..42d67f87c 100644 --- a/vendor/cel.dev/expr/README.md +++ b/vendor/cel.dev/expr/README.md @@ -69,5 +69,3 @@ For more detail, see: * [Language Definition](doc/langdef.md) Released under the [Apache License](LICENSE). - -Disclaimer: This is not an official Google product. diff --git a/vendor/cel.dev/expr/cloudbuild.yaml b/vendor/cel.dev/expr/cloudbuild.yaml index c40881f12..e3e533a04 100644 --- a/vendor/cel.dev/expr/cloudbuild.yaml +++ b/vendor/cel.dev/expr/cloudbuild.yaml @@ -1,5 +1,5 @@ steps: -- name: 'gcr.io/cloud-builders/bazel:7.0.1' +- name: 'gcr.io/cloud-builders/bazel:7.3.2' entrypoint: bazel args: ['build', '...'] id: bazel-build diff --git a/vendor/cel.dev/expr/eval.pb.go b/vendor/cel.dev/expr/eval.pb.go index 8f651f9cc..a7aae0900 100644 --- a/vendor/cel.dev/expr/eval.pb.go +++ b/vendor/cel.dev/expr/eval.pb.go @@ -1,15 +1,15 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.5 +// protoc-gen-go v1.36.3 +// protoc v5.27.1 // source: cel/expr/eval.proto package expr import ( - status "google.golang.org/genproto/googleapis/rpc/status" protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" reflect "reflect" sync "sync" ) @@ -22,21 +22,18 @@ const ( ) type EvalState struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` + Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` unknownFields protoimpl.UnknownFields - - Values []*ExprValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` - Results []*EvalState_Result `protobuf:"bytes,3,rep,name=results,proto3" json:"results,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EvalState) Reset() { *x = EvalState{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EvalState) String() string { @@ -47,7 +44,7 @@ func (*EvalState) ProtoMessage() {} func (x *EvalState) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -77,25 +74,22 @@ func (x *EvalState) GetResults() []*EvalState_Result { } type ExprValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Types that are assignable to Kind: + state protoimpl.MessageState `protogen:"open.v1"` + // Types that are valid to be assigned to Kind: // // *ExprValue_Value // *ExprValue_Error // *ExprValue_Unknown - Kind isExprValue_Kind `protobuf_oneof:"kind"` + Kind isExprValue_Kind `protobuf_oneof:"kind"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache } func (x *ExprValue) Reset() { *x = ExprValue{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ExprValue) String() string { @@ -106,7 +100,7 @@ func (*ExprValue) ProtoMessage() {} func (x *ExprValue) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -121,30 +115,36 @@ func (*ExprValue) Descriptor() ([]byte, []int) { return file_cel_expr_eval_proto_rawDescGZIP(), []int{1} } -func (m *ExprValue) GetKind() isExprValue_Kind { - if m != nil { - return m.Kind +func (x *ExprValue) GetKind() isExprValue_Kind { + if x != nil { + return x.Kind } return nil } func (x *ExprValue) GetValue() *Value { - if x, ok := x.GetKind().(*ExprValue_Value); ok { - return x.Value + if x != nil { + if x, ok := x.Kind.(*ExprValue_Value); ok { + return x.Value + } } return nil } func (x *ExprValue) GetError() *ErrorSet { - if x, ok := x.GetKind().(*ExprValue_Error); ok { - return x.Error + if x != nil { + if x, ok := x.Kind.(*ExprValue_Error); ok { + return x.Error + } } return nil } func (x *ExprValue) GetUnknown() *UnknownSet { - if x, ok := x.GetKind().(*ExprValue_Unknown); ok { - return x.Unknown + if x != nil { + if x, ok := x.Kind.(*ExprValue_Unknown); ok { + return x.Unknown + } } return nil } @@ -172,20 +172,17 @@ func (*ExprValue_Error) isExprValue_Kind() {} func (*ExprValue_Unknown) isExprValue_Kind() {} type ErrorSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Errors []*Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"` unknownFields protoimpl.UnknownFields - - Errors []*status.Status `protobuf:"bytes,1,rep,name=errors,proto3" json:"errors,omitempty"` + sizeCache protoimpl.SizeCache } func (x *ErrorSet) Reset() { *x = ErrorSet{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ErrorSet) String() string { @@ -196,7 +193,7 @@ func (*ErrorSet) ProtoMessage() {} func (x *ErrorSet) ProtoReflect() protoreflect.Message { mi := &file_cel_expr_eval_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -211,28 +208,85 @@ func (*ErrorSet) Descriptor() ([]byte, []int) { return file_cel_expr_eval_proto_rawDescGZIP(), []int{2} } -func (x *ErrorSet) GetErrors() []*status.Status { +func (x *ErrorSet) GetErrors() []*Status { if x != nil { return x.Errors } return nil } -type UnknownSet struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache +type Status struct { + state protoimpl.MessageState `protogen:"open.v1"` + Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Details []*anypb.Any `protobuf:"bytes,3,rep,name=details,proto3" json:"details,omitempty"` unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} - Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"` +func (x *Status) Reset() { + *x = Status{} + mi := &file_cel_expr_eval_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } -func (x *UnknownSet) Reset() { - *x = UnknownSet{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[3] +func (x *Status) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Status) ProtoMessage() {} + +func (x *Status) ProtoReflect() protoreflect.Message { + mi := &file_cel_expr_eval_proto_msgTypes[3] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Status.ProtoReflect.Descriptor instead. +func (*Status) Descriptor() ([]byte, []int) { + return file_cel_expr_eval_proto_rawDescGZIP(), []int{3} +} + +func (x *Status) GetCode() int32 { + if x != nil { + return x.Code } + return 0 +} + +func (x *Status) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *Status) GetDetails() []*anypb.Any { + if x != nil { + return x.Details + } + return nil +} + +type UnknownSet struct { + state protoimpl.MessageState `protogen:"open.v1"` + Exprs []int64 `protobuf:"varint,1,rep,packed,name=exprs,proto3" json:"exprs,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *UnknownSet) Reset() { + *x = UnknownSet{} + mi := &file_cel_expr_eval_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UnknownSet) String() string { @@ -242,8 +296,8 @@ func (x *UnknownSet) String() string { func (*UnknownSet) ProtoMessage() {} func (x *UnknownSet) ProtoReflect() protoreflect.Message { - mi := &file_cel_expr_eval_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_cel_expr_eval_proto_msgTypes[4] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -255,7 +309,7 @@ func (x *UnknownSet) ProtoReflect() protoreflect.Message { // Deprecated: Use UnknownSet.ProtoReflect.Descriptor instead. func (*UnknownSet) Descriptor() ([]byte, []int) { - return file_cel_expr_eval_proto_rawDescGZIP(), []int{3} + return file_cel_expr_eval_proto_rawDescGZIP(), []int{4} } func (x *UnknownSet) GetExprs() []int64 { @@ -266,21 +320,18 @@ func (x *UnknownSet) GetExprs() []int64 { } type EvalState_Result struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache + state protoimpl.MessageState `protogen:"open.v1"` + Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"` + Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` unknownFields protoimpl.UnknownFields - - Expr int64 `protobuf:"varint,1,opt,name=expr,proto3" json:"expr,omitempty"` - Value int64 `protobuf:"varint,2,opt,name=value,proto3" json:"value,omitempty"` + sizeCache protoimpl.SizeCache } func (x *EvalState_Result) Reset() { *x = EvalState_Result{} - if protoimpl.UnsafeEnabled { - mi := &file_cel_expr_eval_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_cel_expr_eval_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *EvalState_Result) String() string { @@ -290,8 +341,8 @@ func (x *EvalState_Result) String() string { func (*EvalState_Result) ProtoMessage() {} func (x *EvalState_Result) ProtoReflect() protoreflect.Message { - mi := &file_cel_expr_eval_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + mi := &file_cel_expr_eval_proto_msgTypes[5] + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -325,39 +376,45 @@ var File_cel_expr_eval_proto protoreflect.FileDescriptor var file_cel_expr_eval_proto_rawDesc = []byte{ 0x0a, 0x13, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x65, 0x76, 0x61, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x1a, - 0x14, 0x63, 0x65, 0x6c, 0x2f, 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x72, 0x70, - 0x63, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa2, - 0x01, 0x0a, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, 0x0a, 0x06, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, - 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, 0x65, 0x6c, - 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, - 0x32, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, 0x78, 0x70, - 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, 0x6c, 0x75, - 0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, 0x6c, 0x2e, - 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, - 0x70, 0x72, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x48, 0x00, 0x52, - 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, - 0x22, 0x36, 0x0a, 0x08, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x2a, 0x0a, 0x06, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x22, 0x0a, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, - 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x42, 0x2c, 0x0a, 0x0c, - 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x45, 0x76, - 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, - 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x14, 0x63, 0x65, 0x6c, 0x2f, + 0x65, 0x78, 0x70, 0x72, 0x2f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0xa2, 0x01, 0x0a, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x2b, + 0x0a, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, + 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x52, 0x06, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x34, 0x0a, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x63, + 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x76, 0x61, 0x6c, 0x53, 0x74, 0x61, 0x74, + 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x1a, 0x32, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x65, + 0x78, 0x70, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x65, 0x78, 0x70, 0x72, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x9a, 0x01, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x72, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x27, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x48, 0x00, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x2a, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x63, 0x65, + 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x48, + 0x00, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x30, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, + 0x6f, 0x77, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x63, 0x65, 0x6c, 0x2e, + 0x65, 0x78, 0x70, 0x72, 0x2e, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x48, + 0x00, 0x52, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x42, 0x06, 0x0a, 0x04, 0x6b, 0x69, + 0x6e, 0x64, 0x22, 0x34, 0x0a, 0x08, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x53, 0x65, 0x74, 0x12, 0x28, + 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x63, 0x65, 0x6c, 0x2e, 0x65, 0x78, 0x70, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x22, 0x66, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, + 0x12, 0x2e, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, + 0x22, 0x22, 0x0a, 0x0a, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x65, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x78, 0x70, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x03, 0x52, 0x05, 0x65, + 0x78, 0x70, 0x72, 0x73, 0x42, 0x2c, 0x0a, 0x0c, 0x64, 0x65, 0x76, 0x2e, 0x63, 0x65, 0x6c, 0x2e, + 0x65, 0x78, 0x70, 0x72, 0x42, 0x09, 0x45, 0x76, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x0c, 0x63, 0x65, 0x6c, 0x2e, 0x64, 0x65, 0x76, 0x2f, 0x65, 0x78, 0x70, 0x72, 0xf8, + 0x01, 0x01, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -372,28 +429,30 @@ func file_cel_expr_eval_proto_rawDescGZIP() []byte { return file_cel_expr_eval_proto_rawDescData } -var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_cel_expr_eval_proto_goTypes = []interface{}{ +var file_cel_expr_eval_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_cel_expr_eval_proto_goTypes = []any{ (*EvalState)(nil), // 0: cel.expr.EvalState (*ExprValue)(nil), // 1: cel.expr.ExprValue (*ErrorSet)(nil), // 2: cel.expr.ErrorSet - (*UnknownSet)(nil), // 3: cel.expr.UnknownSet - (*EvalState_Result)(nil), // 4: cel.expr.EvalState.Result - (*Value)(nil), // 5: cel.expr.Value - (*status.Status)(nil), // 6: google.rpc.Status + (*Status)(nil), // 3: cel.expr.Status + (*UnknownSet)(nil), // 4: cel.expr.UnknownSet + (*EvalState_Result)(nil), // 5: cel.expr.EvalState.Result + (*Value)(nil), // 6: cel.expr.Value + (*anypb.Any)(nil), // 7: google.protobuf.Any } var file_cel_expr_eval_proto_depIdxs = []int32{ 1, // 0: cel.expr.EvalState.values:type_name -> cel.expr.ExprValue - 4, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result - 5, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value + 5, // 1: cel.expr.EvalState.results:type_name -> cel.expr.EvalState.Result + 6, // 2: cel.expr.ExprValue.value:type_name -> cel.expr.Value 2, // 3: cel.expr.ExprValue.error:type_name -> cel.expr.ErrorSet - 3, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet - 6, // 5: cel.expr.ErrorSet.errors:type_name -> google.rpc.Status - 6, // [6:6] is the sub-list for method output_type - 6, // [6:6] is the sub-list for method input_type - 6, // [6:6] is the sub-list for extension type_name - 6, // [6:6] is the sub-list for extension extendee - 0, // [0:6] is the sub-list for field type_name + 4, // 4: cel.expr.ExprValue.unknown:type_name -> cel.expr.UnknownSet + 3, // 5: cel.expr.ErrorSet.errors:type_name -> cel.expr.Status + 7, // 6: cel.expr.Status.details:type_name -> google.protobuf.Any + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_cel_expr_eval_proto_init() } @@ -402,69 +461,7 @@ func file_cel_expr_eval_proto_init() { return } file_cel_expr_value_proto_init() - if !protoimpl.UnsafeEnabled { - file_cel_expr_eval_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EvalState); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExprValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ErrorSet); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UnknownSet); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_cel_expr_eval_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*EvalState_Result); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_cel_expr_eval_proto_msgTypes[1].OneofWrappers = []any{ (*ExprValue_Value)(nil), (*ExprValue_Error)(nil), (*ExprValue_Unknown)(nil), @@ -475,7 +472,7 @@ func file_cel_expr_eval_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_cel_expr_eval_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/vendor/github.com/JeffAshton/win_pdh/AUTHORS b/vendor/github.com/JeffAshton/win_pdh/AUTHORS deleted file mode 100644 index 7129f3d73..000000000 --- a/vendor/github.com/JeffAshton/win_pdh/AUTHORS +++ /dev/null @@ -1,14 +0,0 @@ -# This is the official list of 'win_pdh' authors for copyright purposes. - -# Names should be added to this file as -# Name or Organization -# The email address is not required for organizations. - -# Please keep the list sorted. - -# Contributors -# ============ - -Alexander Neumann -Joseph Watson -Kevin Pors diff --git a/vendor/github.com/JeffAshton/win_pdh/LICENSE b/vendor/github.com/JeffAshton/win_pdh/LICENSE deleted file mode 100644 index 5bf54be11..000000000 --- a/vendor/github.com/JeffAshton/win_pdh/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2010 The win_pdh Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. -3. The names of the authors may not be used to endorse or promote products - derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, -INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/github.com/JeffAshton/win_pdh/README.mdown b/vendor/github.com/JeffAshton/win_pdh/README.mdown deleted file mode 100644 index 268cd9f84..000000000 --- a/vendor/github.com/JeffAshton/win_pdh/README.mdown +++ /dev/null @@ -1,15 +0,0 @@ -About win_pdh -============= - -win_pdh is a Windows Performance Data Helper wrapper package for Go. - -Originally part of [walk](https://github.com/lxn/walk) and [win](https://github.com/lxn/win), it is now a separate -project. - -Setup -===== - -Make sure you have a working Go installation. -See [Getting Started](http://golang.org/doc/install.html) - -Now run `go get github.com/JeffAshton/win_pdh` diff --git a/vendor/github.com/JeffAshton/win_pdh/pdh.go b/vendor/github.com/JeffAshton/win_pdh/pdh.go deleted file mode 100644 index 56199001a..000000000 --- a/vendor/github.com/JeffAshton/win_pdh/pdh.go +++ /dev/null @@ -1,453 +0,0 @@ -// Copyright 2013 The win_pdh Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build windows - -package win_pdh - -import ( - "syscall" - "unsafe" -) - -// Error codes -const ( - ERROR_SUCCESS = 0 - ERROR_INVALID_FUNCTION = 1 -) - -type ( - HANDLE uintptr -) - -// PDH error codes, which can be returned by all Pdh* functions. Taken from mingw-w64 pdhmsg.h -const ( - PDH_CSTATUS_VALID_DATA = 0x00000000 // The returned data is valid. - PDH_CSTATUS_NEW_DATA = 0x00000001 // The return data value is valid and different from the last sample. - PDH_CSTATUS_NO_MACHINE = 0x800007D0 // Unable to connect to the specified computer, or the computer is offline. - PDH_CSTATUS_NO_INSTANCE = 0x800007D1 - PDH_MORE_DATA = 0x800007D2 // The PdhGetFormattedCounterArray* function can return this if there's 'more data to be displayed'. - PDH_CSTATUS_ITEM_NOT_VALIDATED = 0x800007D3 - PDH_RETRY = 0x800007D4 - PDH_NO_DATA = 0x800007D5 // The query does not currently contain any counters (for example, limited access) - PDH_CALC_NEGATIVE_DENOMINATOR = 0x800007D6 - PDH_CALC_NEGATIVE_TIMEBASE = 0x800007D7 - PDH_CALC_NEGATIVE_VALUE = 0x800007D8 - PDH_DIALOG_CANCELLED = 0x800007D9 - PDH_END_OF_LOG_FILE = 0x800007DA - PDH_ASYNC_QUERY_TIMEOUT = 0x800007DB - PDH_CANNOT_SET_DEFAULT_REALTIME_DATASOURCE = 0x800007DC - PDH_CSTATUS_NO_OBJECT = 0xC0000BB8 - PDH_CSTATUS_NO_COUNTER = 0xC0000BB9 // The specified counter could not be found. - PDH_CSTATUS_INVALID_DATA = 0xC0000BBA // The counter was successfully found, but the data returned is not valid. - PDH_MEMORY_ALLOCATION_FAILURE = 0xC0000BBB - PDH_INVALID_HANDLE = 0xC0000BBC - PDH_INVALID_ARGUMENT = 0xC0000BBD // Required argument is missing or incorrect. - PDH_FUNCTION_NOT_FOUND = 0xC0000BBE - PDH_CSTATUS_NO_COUNTERNAME = 0xC0000BBF - PDH_CSTATUS_BAD_COUNTERNAME = 0xC0000BC0 // Unable to parse the counter path. Check the format and syntax of the specified path. - PDH_INVALID_BUFFER = 0xC0000BC1 - PDH_INSUFFICIENT_BUFFER = 0xC0000BC2 - PDH_CANNOT_CONNECT_MACHINE = 0xC0000BC3 - PDH_INVALID_PATH = 0xC0000BC4 - PDH_INVALID_INSTANCE = 0xC0000BC5 - PDH_INVALID_DATA = 0xC0000BC6 // specified counter does not contain valid data or a successful status code. - PDH_NO_DIALOG_DATA = 0xC0000BC7 - PDH_CANNOT_READ_NAME_STRINGS = 0xC0000BC8 - PDH_LOG_FILE_CREATE_ERROR = 0xC0000BC9 - PDH_LOG_FILE_OPEN_ERROR = 0xC0000BCA - PDH_LOG_TYPE_NOT_FOUND = 0xC0000BCB - PDH_NO_MORE_DATA = 0xC0000BCC - PDH_ENTRY_NOT_IN_LOG_FILE = 0xC0000BCD - PDH_DATA_SOURCE_IS_LOG_FILE = 0xC0000BCE - PDH_DATA_SOURCE_IS_REAL_TIME = 0xC0000BCF - PDH_UNABLE_READ_LOG_HEADER = 0xC0000BD0 - PDH_FILE_NOT_FOUND = 0xC0000BD1 - PDH_FILE_ALREADY_EXISTS = 0xC0000BD2 - PDH_NOT_IMPLEMENTED = 0xC0000BD3 - PDH_STRING_NOT_FOUND = 0xC0000BD4 - PDH_UNABLE_MAP_NAME_FILES = 0x80000BD5 - PDH_UNKNOWN_LOG_FORMAT = 0xC0000BD6 - PDH_UNKNOWN_LOGSVC_COMMAND = 0xC0000BD7 - PDH_LOGSVC_QUERY_NOT_FOUND = 0xC0000BD8 - PDH_LOGSVC_NOT_OPENED = 0xC0000BD9 - PDH_WBEM_ERROR = 0xC0000BDA - PDH_ACCESS_DENIED = 0xC0000BDB - PDH_LOG_FILE_TOO_SMALL = 0xC0000BDC - PDH_INVALID_DATASOURCE = 0xC0000BDD - PDH_INVALID_SQLDB = 0xC0000BDE - PDH_NO_COUNTERS = 0xC0000BDF - PDH_SQL_ALLOC_FAILED = 0xC0000BE0 - PDH_SQL_ALLOCCON_FAILED = 0xC0000BE1 - PDH_SQL_EXEC_DIRECT_FAILED = 0xC0000BE2 - PDH_SQL_FETCH_FAILED = 0xC0000BE3 - PDH_SQL_ROWCOUNT_FAILED = 0xC0000BE4 - PDH_SQL_MORE_RESULTS_FAILED = 0xC0000BE5 - PDH_SQL_CONNECT_FAILED = 0xC0000BE6 - PDH_SQL_BIND_FAILED = 0xC0000BE7 - PDH_CANNOT_CONNECT_WMI_SERVER = 0xC0000BE8 - PDH_PLA_COLLECTION_ALREADY_RUNNING = 0xC0000BE9 - PDH_PLA_ERROR_SCHEDULE_OVERLAP = 0xC0000BEA - PDH_PLA_COLLECTION_NOT_FOUND = 0xC0000BEB - PDH_PLA_ERROR_SCHEDULE_ELAPSED = 0xC0000BEC - PDH_PLA_ERROR_NOSTART = 0xC0000BED - PDH_PLA_ERROR_ALREADY_EXISTS = 0xC0000BEE - PDH_PLA_ERROR_TYPE_MISMATCH = 0xC0000BEF - PDH_PLA_ERROR_FILEPATH = 0xC0000BF0 - PDH_PLA_SERVICE_ERROR = 0xC0000BF1 - PDH_PLA_VALIDATION_ERROR = 0xC0000BF2 - PDH_PLA_VALIDATION_WARNING = 0x80000BF3 - PDH_PLA_ERROR_NAME_TOO_LONG = 0xC0000BF4 - PDH_INVALID_SQL_LOG_FORMAT = 0xC0000BF5 - PDH_COUNTER_ALREADY_IN_QUERY = 0xC0000BF6 - PDH_BINARY_LOG_CORRUPT = 0xC0000BF7 - PDH_LOG_SAMPLE_TOO_SMALL = 0xC0000BF8 - PDH_OS_LATER_VERSION = 0xC0000BF9 - PDH_OS_EARLIER_VERSION = 0xC0000BFA - PDH_INCORRECT_APPEND_TIME = 0xC0000BFB - PDH_UNMATCHED_APPEND_COUNTER = 0xC0000BFC - PDH_SQL_ALTER_DETAIL_FAILED = 0xC0000BFD - PDH_QUERY_PERF_DATA_TIMEOUT = 0xC0000BFE -) - -// Formatting options for GetFormattedCounterValue(). -const ( - PDH_FMT_RAW = 0x00000010 - PDH_FMT_ANSI = 0x00000020 - PDH_FMT_UNICODE = 0x00000040 - PDH_FMT_LONG = 0x00000100 // Return data as a long int. - PDH_FMT_DOUBLE = 0x00000200 // Return data as a double precision floating point real. - PDH_FMT_LARGE = 0x00000400 // Return data as a 64 bit integer. - PDH_FMT_NOSCALE = 0x00001000 // can be OR-ed: Do not apply the counter's default scaling factor. - PDH_FMT_1000 = 0x00002000 // can be OR-ed: multiply the actual value by 1,000. - PDH_FMT_NODATA = 0x00004000 // can be OR-ed: unknown what this is for, MSDN says nothing. - PDH_FMT_NOCAP100 = 0x00008000 // can be OR-ed: do not cap values > 100. - PERF_DETAIL_COSTLY = 0x00010000 - PERF_DETAIL_STANDARD = 0x0000FFFF -) - -type ( - PDH_HQUERY HANDLE // query handle - PDH_HCOUNTER HANDLE // counter handle -) - -// Union specialization for double values -type PDH_FMT_COUNTERVALUE_DOUBLE struct { - CStatus uint32 - DoubleValue float64 -} - -// Union specialization for 64 bit integer values -type PDH_FMT_COUNTERVALUE_LARGE struct { - CStatus uint32 - LargeValue int64 -} - -// Union specialization for long values -type PDH_FMT_COUNTERVALUE_LONG struct { - CStatus uint32 - LongValue int32 - padding [4]byte -} - -// Union specialization for double values, used by PdhGetFormattedCounterArrayDouble() -type PDH_FMT_COUNTERVALUE_ITEM_DOUBLE struct { - SzName *uint16 // pointer to a string - FmtValue PDH_FMT_COUNTERVALUE_DOUBLE -} - -// Union specialization for 'large' values, used by PdhGetFormattedCounterArrayLarge() -type PDH_FMT_COUNTERVALUE_ITEM_LARGE struct { - SzName *uint16 // pointer to a string - FmtValue PDH_FMT_COUNTERVALUE_LARGE -} - -// Union specialization for long values, used by PdhGetFormattedCounterArrayLong() -type PDH_FMT_COUNTERVALUE_ITEM_LONG struct { - SzName *uint16 // pointer to a string - FmtValue PDH_FMT_COUNTERVALUE_LONG -} - -var ( - // Library - libpdhDll *syscall.DLL - - // Functions - pdh_AddCounterW *syscall.Proc - pdh_AddEnglishCounterW *syscall.Proc - pdh_CloseQuery *syscall.Proc - pdh_CollectQueryData *syscall.Proc - pdh_GetFormattedCounterValue *syscall.Proc - pdh_GetFormattedCounterArrayW *syscall.Proc - pdh_OpenQuery *syscall.Proc - pdh_ValidatePathW *syscall.Proc -) - -func init() { - // Library - libpdhDll = syscall.MustLoadDLL("pdh.dll") - - // Functions - pdh_AddCounterW = libpdhDll.MustFindProc("PdhAddCounterW") - pdh_AddEnglishCounterW, _ = libpdhDll.FindProc("PdhAddEnglishCounterW") // XXX: only supported on versions > Vista. - pdh_CloseQuery = libpdhDll.MustFindProc("PdhCloseQuery") - pdh_CollectQueryData = libpdhDll.MustFindProc("PdhCollectQueryData") - pdh_GetFormattedCounterValue = libpdhDll.MustFindProc("PdhGetFormattedCounterValue") - pdh_GetFormattedCounterArrayW = libpdhDll.MustFindProc("PdhGetFormattedCounterArrayW") - pdh_OpenQuery = libpdhDll.MustFindProc("PdhOpenQuery") - pdh_ValidatePathW = libpdhDll.MustFindProc("PdhValidatePathW") -} - -// Adds the specified counter to the query. This is the internationalized version. Preferably, use the -// function PdhAddEnglishCounter instead. hQuery is the query handle, which has been fetched by PdhOpenQuery. -// szFullCounterPath is a full, internationalized counter path (this will differ per Windows language version). -// dwUserData is a 'user-defined value', which becomes part of the counter information. To retrieve this value -// later, call PdhGetCounterInfo() and access dwQueryUserData of the PDH_COUNTER_INFO structure. -// -// Examples of szFullCounterPath (in an English version of Windows): -// -// \\Processor(_Total)\\% Idle Time -// \\Processor(_Total)\\% Processor Time -// \\LogicalDisk(C:)\% Free Space -// -// To view all (internationalized...) counters on a system, there are three non-programmatic ways: perfmon utility, -// the typeperf command, and the the registry editor. perfmon.exe is perhaps the easiest way, because it's basically a -// full implemention of the pdh.dll API, except with a GUI and all that. The registry setting also provides an -// interface to the available counters, and can be found at the following key: -// -// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage -// -// This registry key contains several values as follows: -// -// 1 -// 1847 -// 2 -// System -// 4 -// Memory -// 6 -// % Processor Time -// ... many, many more -// -// Somehow, these numeric values can be used as szFullCounterPath too: -// -// \2\6 will correspond to \\System\% Processor Time -// -// The typeperf command may also be pretty easy. To find all performance counters, simply execute: -// -// typeperf -qx -func PdhAddCounter(hQuery PDH_HQUERY, szFullCounterPath string, dwUserData uintptr, phCounter *PDH_HCOUNTER) uint32 { - ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath) - ret, _, _ := pdh_AddCounterW.Call( - uintptr(hQuery), - uintptr(unsafe.Pointer(ptxt)), - dwUserData, - uintptr(unsafe.Pointer(phCounter))) - - return uint32(ret) -} - -// Adds the specified language-neutral counter to the query. See the PdhAddCounter function. This function only exists on -// Windows versions higher than Vista. -func PdhAddEnglishCounter(hQuery PDH_HQUERY, szFullCounterPath string, dwUserData uintptr, phCounter *PDH_HCOUNTER) uint32 { - if pdh_AddEnglishCounterW == nil { - return ERROR_INVALID_FUNCTION - } - - ptxt, _ := syscall.UTF16PtrFromString(szFullCounterPath) - ret, _, _ := pdh_AddEnglishCounterW.Call( - uintptr(hQuery), - uintptr(unsafe.Pointer(ptxt)), - dwUserData, - uintptr(unsafe.Pointer(phCounter))) - - return uint32(ret) -} - -// Closes all counters contained in the specified query, closes all handles related to the query, -// and frees all memory associated with the query. -func PdhCloseQuery(hQuery PDH_HQUERY) uint32 { - ret, _, _ := pdh_CloseQuery.Call(uintptr(hQuery)) - - return uint32(ret) -} - -// Collects the current raw data value for all counters in the specified query and updates the status -// code of each counter. With some counters, this function needs to be repeatedly called before the value -// of the counter can be extracted with PdhGetFormattedCounterValue(). For example, the following code -// requires at least two calls: -// -// var handle win.PDH_HQUERY -// var counterHandle win.PDH_HCOUNTER -// ret := win.PdhOpenQuery(0, 0, &handle) -// ret = win.PdhAddEnglishCounter(handle, "\\Processor(_Total)\\% Idle Time", 0, &counterHandle) -// var derp win.PDH_FMT_COUNTERVALUE_DOUBLE -// -// ret = win.PdhCollectQueryData(handle) -// fmt.Printf("Collect return code is %x\n", ret) // return code will be PDH_CSTATUS_INVALID_DATA -// ret = win.PdhGetFormattedCounterValueDouble(counterHandle, 0, &derp) -// -// ret = win.PdhCollectQueryData(handle) -// fmt.Printf("Collect return code is %x\n", ret) // return code will be ERROR_SUCCESS -// ret = win.PdhGetFormattedCounterValueDouble(counterHandle, 0, &derp) -// -// The PdhCollectQueryData will return an error in the first call because it needs two values for -// displaying the correct data for the processor idle time. The second call will have a 0 return code. -func PdhCollectQueryData(hQuery PDH_HQUERY) uint32 { - ret, _, _ := pdh_CollectQueryData.Call(uintptr(hQuery)) - - return uint32(ret) -} - -// Formats the given hCounter using a 'double'. The result is set into the specialized union struct pValue. -// This function does not directly translate to a Windows counterpart due to union specialization tricks. -func PdhGetFormattedCounterValueDouble(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_DOUBLE) uint32 { - ret, _, _ := pdh_GetFormattedCounterValue.Call( - uintptr(hCounter), - uintptr(PDH_FMT_DOUBLE), - uintptr(unsafe.Pointer(lpdwType)), - uintptr(unsafe.Pointer(pValue))) - - return uint32(ret) -} - -// Formats the given hCounter using a large int (int64). The result is set into the specialized union struct pValue. -// This function does not directly translate to a Windows counterpart due to union specialization tricks. -func PdhGetFormattedCounterValueLarge(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_LARGE) uint32 { - ret, _, _ := pdh_GetFormattedCounterValue.Call( - uintptr(hCounter), - uintptr(PDH_FMT_LARGE), - uintptr(unsafe.Pointer(lpdwType)), - uintptr(unsafe.Pointer(pValue))) - - return uint32(ret) -} - -// Formats the given hCounter using a 'long'. The result is set into the specialized union struct pValue. -// This function does not directly translate to a Windows counterpart due to union specialization tricks. -// -// BUG(krpors): Testing this function on multiple systems yielded inconsistent results. For instance, -// the pValue.LongValue kept the value '192' on test system A, but on B this was '0', while the padding -// bytes of the struct got the correct value. Until someone can figure out this behaviour, prefer to use -// the Double or Large counterparts instead. These functions provide actually the same data, except in -// a different, working format. -func PdhGetFormattedCounterValueLong(hCounter PDH_HCOUNTER, lpdwType *uint32, pValue *PDH_FMT_COUNTERVALUE_LONG) uint32 { - ret, _, _ := pdh_GetFormattedCounterValue.Call( - uintptr(hCounter), - uintptr(PDH_FMT_LONG), - uintptr(unsafe.Pointer(lpdwType)), - uintptr(unsafe.Pointer(pValue))) - - return uint32(ret) -} - -// Returns an array of formatted counter values. Use this function when you want to format the counter values of a -// counter that contains a wildcard character for the instance name. The itemBuffer must a slice of type PDH_FMT_COUNTERVALUE_ITEM_DOUBLE. -// An example of how this function can be used: -// -// okPath := "\\Process(*)\\% Processor Time" // notice the wildcard * character -// -// // ommitted all necessary stuff ... -// -// var bufSize uint32 -// var bufCount uint32 -// var size uint32 = uint32(unsafe.Sizeof(win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{})) -// var emptyBuf [1]win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr. -// -// for { -// // collect -// ret := win.PdhCollectQueryData(queryHandle) -// if ret == win.ERROR_SUCCESS { -// ret = win.PdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &emptyBuf[0]) // uses null ptr here according to MSDN. -// if ret == win.PDH_MORE_DATA { -// filledBuf := make([]win.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, bufCount*size) -// ret = win.PdhGetFormattedCounterArrayDouble(counterHandle, &bufSize, &bufCount, &filledBuf[0]) -// for i := 0; i < int(bufCount); i++ { -// c := filledBuf[i] -// var s string = win.UTF16PtrToString(c.SzName) -// fmt.Printf("Index %d -> %s, value %v\n", i, s, c.FmtValue.DoubleValue) -// } -// -// filledBuf = nil -// // Need to at least set bufSize to zero, because if not, the function will not -// // return PDH_MORE_DATA and will not set the bufSize. -// bufCount = 0 -// bufSize = 0 -// } -// -// time.Sleep(2000 * time.Millisecond) -// } -// } -func PdhGetFormattedCounterArrayDouble(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *PDH_FMT_COUNTERVALUE_ITEM_DOUBLE) uint32 { - ret, _, _ := pdh_GetFormattedCounterArrayW.Call( - uintptr(hCounter), - uintptr(PDH_FMT_DOUBLE), - uintptr(unsafe.Pointer(lpdwBufferSize)), - uintptr(unsafe.Pointer(lpdwBufferCount)), - uintptr(unsafe.Pointer(itemBuffer))) - - return uint32(ret) -} - -// Returns an array of formatted counter values. Use this function when you want to format the counter values of a -// counter that contains a wildcard character for the instance name. The itemBuffer must a slice of type PDH_FMT_COUNTERVALUE_ITEM_LARGE. -// For an example usage, see PdhGetFormattedCounterArrayDouble. -func PdhGetFormattedCounterArrayLarge(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *PDH_FMT_COUNTERVALUE_ITEM_LARGE) uint32 { - ret, _, _ := pdh_GetFormattedCounterArrayW.Call( - uintptr(hCounter), - uintptr(PDH_FMT_LARGE), - uintptr(unsafe.Pointer(lpdwBufferSize)), - uintptr(unsafe.Pointer(lpdwBufferCount)), - uintptr(unsafe.Pointer(itemBuffer))) - - return uint32(ret) -} - -// Returns an array of formatted counter values. Use this function when you want to format the counter values of a -// counter that contains a wildcard character for the instance name. The itemBuffer must a slice of type PDH_FMT_COUNTERVALUE_ITEM_LONG. -// For an example usage, see PdhGetFormattedCounterArrayDouble. -// -// BUG(krpors): See description of PdhGetFormattedCounterValueLong(). -func PdhGetFormattedCounterArrayLong(hCounter PDH_HCOUNTER, lpdwBufferSize *uint32, lpdwBufferCount *uint32, itemBuffer *PDH_FMT_COUNTERVALUE_ITEM_LONG) uint32 { - ret, _, _ := pdh_GetFormattedCounterArrayW.Call( - uintptr(hCounter), - uintptr(PDH_FMT_LONG), - uintptr(unsafe.Pointer(lpdwBufferSize)), - uintptr(unsafe.Pointer(lpdwBufferCount)), - uintptr(unsafe.Pointer(itemBuffer))) - - return uint32(ret) -} - -// Creates a new query that is used to manage the collection of performance data. -// szDataSource is a null terminated string that specifies the name of the log file from which to -// retrieve the performance data. If 0, performance data is collected from a real-time data source. -// dwUserData is a user-defined value to associate with this query. To retrieve the user data later, -// call PdhGetCounterInfo and access dwQueryUserData of the PDH_COUNTER_INFO structure. phQuery is -// the handle to the query, and must be used in subsequent calls. This function returns a PDH_ -// constant error code, or ERROR_SUCCESS if the call succeeded. -func PdhOpenQuery(szDataSource uintptr, dwUserData uintptr, phQuery *PDH_HQUERY) uint32 { - ret, _, _ := pdh_OpenQuery.Call( - szDataSource, - dwUserData, - uintptr(unsafe.Pointer(phQuery))) - - return uint32(ret) -} - -// Validates a path. Will return ERROR_SUCCESS when ok, or PDH_CSTATUS_BAD_COUNTERNAME when the path is -// erroneous. -func PdhValidatePath(path string) uint32 { - ptxt, _ := syscall.UTF16PtrFromString(path) - ret, _, _ := pdh_ValidatePathW.Call(uintptr(unsafe.Pointer(ptxt))) - - return uint32(ret) -} - -func UTF16PtrToString(s *uint16) string { - if s == nil { - return "" - } - return syscall.UTF16ToString((*[1 << 29]uint16)(unsafe.Pointer(s))[0:]) -} diff --git a/vendor/github.com/Microsoft/go-winio/.gitattributes b/vendor/github.com/Microsoft/go-winio/.gitattributes deleted file mode 100644 index 94f480de9..000000000 --- a/vendor/github.com/Microsoft/go-winio/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* text=auto eol=lf \ No newline at end of file diff --git a/vendor/github.com/Microsoft/go-winio/.gitignore b/vendor/github.com/Microsoft/go-winio/.gitignore deleted file mode 100644 index 815e20660..000000000 --- a/vendor/github.com/Microsoft/go-winio/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -.vscode/ - -*.exe - -# testing -testdata - -# go workspaces -go.work -go.work.sum diff --git a/vendor/github.com/Microsoft/go-winio/.golangci.yml b/vendor/github.com/Microsoft/go-winio/.golangci.yml deleted file mode 100644 index faedfe937..000000000 --- a/vendor/github.com/Microsoft/go-winio/.golangci.yml +++ /dev/null @@ -1,147 +0,0 @@ -linters: - enable: - # style - - containedctx # struct contains a context - - dupl # duplicate code - - errname # erorrs are named correctly - - nolintlint # "//nolint" directives are properly explained - - revive # golint replacement - - unconvert # unnecessary conversions - - wastedassign - - # bugs, performance, unused, etc ... - - contextcheck # function uses a non-inherited context - - errorlint # errors not wrapped for 1.13 - - exhaustive # check exhaustiveness of enum switch statements - - gofmt # files are gofmt'ed - - gosec # security - - nilerr # returns nil even with non-nil error - - thelper # test helpers without t.Helper() - - unparam # unused function params - -issues: - exclude-dirs: - - pkg/etw/sample - - exclude-rules: - # err is very often shadowed in nested scopes - - linters: - - govet - text: '^shadow: declaration of "err" shadows declaration' - - # ignore long lines for skip autogen directives - - linters: - - revive - text: "^line-length-limit: " - source: "^//(go:generate|sys) " - - #TODO: remove after upgrading to go1.18 - # ignore comment spacing for nolint and sys directives - - linters: - - revive - text: "^comment-spacings: no space between comment delimiter and comment text" - source: "//(cspell:|nolint:|sys |todo)" - - # not on go 1.18 yet, so no any - - linters: - - revive - text: "^use-any: since GO 1.18 'interface{}' can be replaced by 'any'" - - # allow unjustified ignores of error checks in defer statements - - linters: - - nolintlint - text: "^directive `//nolint:errcheck` should provide explanation" - source: '^\s*defer ' - - # allow unjustified ignores of error lints for io.EOF - - linters: - - nolintlint - text: "^directive `//nolint:errorlint` should provide explanation" - source: '[=|!]= io.EOF' - - -linters-settings: - exhaustive: - default-signifies-exhaustive: true - govet: - enable-all: true - disable: - # struct order is often for Win32 compat - # also, ignore pointer bytes/GC issues for now until performance becomes an issue - - fieldalignment - nolintlint: - require-explanation: true - require-specific: true - revive: - # revive is more configurable than static check, so likely the preferred alternative to static-check - # (once the perf issue is solved: https://github.com/golangci/golangci-lint/issues/2997) - enable-all-rules: - true - # https://github.com/mgechev/revive/blob/master/RULES_DESCRIPTIONS.md - rules: - # rules with required arguments - - name: argument-limit - disabled: true - - name: banned-characters - disabled: true - - name: cognitive-complexity - disabled: true - - name: cyclomatic - disabled: true - - name: file-header - disabled: true - - name: function-length - disabled: true - - name: function-result-limit - disabled: true - - name: max-public-structs - disabled: true - # geneally annoying rules - - name: add-constant # complains about any and all strings and integers - disabled: true - - name: confusing-naming # we frequently use "Foo()" and "foo()" together - disabled: true - - name: flag-parameter # excessive, and a common idiom we use - disabled: true - - name: unhandled-error # warns over common fmt.Print* and io.Close; rely on errcheck instead - disabled: true - # general config - - name: line-length-limit - arguments: - - 140 - - name: var-naming - arguments: - - [] - - - CID - - CRI - - CTRD - - DACL - - DLL - - DOS - - ETW - - FSCTL - - GCS - - GMSA - - HCS - - HV - - IO - - LCOW - - LDAP - - LPAC - - LTSC - - MMIO - - NT - - OCI - - PMEM - - PWSH - - RX - - SACl - - SID - - SMB - - TX - - VHD - - VHDX - - VMID - - VPCI - - WCOW - - WIM diff --git a/vendor/github.com/Microsoft/go-winio/CODEOWNERS b/vendor/github.com/Microsoft/go-winio/CODEOWNERS deleted file mode 100644 index ae1b4942b..000000000 --- a/vendor/github.com/Microsoft/go-winio/CODEOWNERS +++ /dev/null @@ -1 +0,0 @@ - * @microsoft/containerplat diff --git a/vendor/github.com/Microsoft/go-winio/LICENSE b/vendor/github.com/Microsoft/go-winio/LICENSE deleted file mode 100644 index b8b569d77..000000000 --- a/vendor/github.com/Microsoft/go-winio/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Microsoft - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/vendor/github.com/Microsoft/go-winio/README.md b/vendor/github.com/Microsoft/go-winio/README.md deleted file mode 100644 index 7474b4f0b..000000000 --- a/vendor/github.com/Microsoft/go-winio/README.md +++ /dev/null @@ -1,89 +0,0 @@ -# go-winio [![Build Status](https://github.com/microsoft/go-winio/actions/workflows/ci.yml/badge.svg)](https://github.com/microsoft/go-winio/actions/workflows/ci.yml) - -This repository contains utilities for efficiently performing Win32 IO operations in -Go. Currently, this is focused on accessing named pipes and other file handles, and -for using named pipes as a net transport. - -This code relies on IO completion ports to avoid blocking IO on system threads, allowing Go -to reuse the thread to schedule another goroutine. This limits support to Windows Vista and -newer operating systems. This is similar to the implementation of network sockets in Go's net -package. - -Please see the LICENSE file for licensing information. - -## Contributing - -This project welcomes contributions and suggestions. -Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that -you have the right to, and actually do, grant us the rights to use your contribution. -For details, visit [Microsoft CLA](https://cla.microsoft.com). - -When you submit a pull request, a CLA-bot will automatically determine whether you need to -provide a CLA and decorate the PR appropriately (e.g., label, comment). -Simply follow the instructions provided by the bot. -You will only need to do this once across all repos using our CLA. - -Additionally, the pull request pipeline requires the following steps to be performed before -mergining. - -### Code Sign-Off - -We require that contributors sign their commits using [`git commit --signoff`][git-commit-s] -to certify they either authored the work themselves or otherwise have permission to use it in this project. - -A range of commits can be signed off using [`git rebase --signoff`][git-rebase-s]. - -Please see [the developer certificate](https://developercertificate.org) for more info, -as well as to make sure that you can attest to the rules listed. -Our CI uses the DCO Github app to ensure that all commits in a given PR are signed-off. - -### Linting - -Code must pass a linting stage, which uses [`golangci-lint`][lint]. -The linting settings are stored in [`.golangci.yaml`](./.golangci.yaml), and can be run -automatically with VSCode by adding the following to your workspace or folder settings: - -```json - "go.lintTool": "golangci-lint", - "go.lintOnSave": "package", -``` - -Additional editor [integrations options are also available][lint-ide]. - -Alternatively, `golangci-lint` can be [installed locally][lint-install] and run from the repo root: - -```shell -# use . or specify a path to only lint a package -# to show all lint errors, use flags "--max-issues-per-linter=0 --max-same-issues=0" -> golangci-lint run ./... -``` - -### Go Generate - -The pipeline checks that auto-generated code, via `go generate`, are up to date. - -This can be done for the entire repo: - -```shell -> go generate ./... -``` - -## Code of Conduct - -This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). -For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or -contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. - -## Special Thanks - -Thanks to [natefinch][natefinch] for the inspiration for this library. -See [npipe](https://github.com/natefinch/npipe) for another named pipe implementation. - -[lint]: https://golangci-lint.run/ -[lint-ide]: https://golangci-lint.run/usage/integrations/#editor-integration -[lint-install]: https://golangci-lint.run/usage/install/#local-installation - -[git-commit-s]: https://git-scm.com/docs/git-commit#Documentation/git-commit.txt--s -[git-rebase-s]: https://git-scm.com/docs/git-rebase#Documentation/git-rebase.txt---signoff - -[natefinch]: https://github.com/natefinch diff --git a/vendor/github.com/Microsoft/go-winio/SECURITY.md b/vendor/github.com/Microsoft/go-winio/SECURITY.md deleted file mode 100644 index 869fdfe2b..000000000 --- a/vendor/github.com/Microsoft/go-winio/SECURITY.md +++ /dev/null @@ -1,41 +0,0 @@ - - -## Security - -Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [our GitHub organizations](https://opensource.microsoft.com/). - -If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/opensource/security/definition), please report it to us as described below. - -## Reporting Security Issues - -**Please do not report security vulnerabilities through public GitHub issues.** - -Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/opensource/security/create-report). - -If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/opensource/security/pgpkey). - -You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://aka.ms/opensource/security/msrc). - -Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: - - * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) - * Full paths of source file(s) related to the manifestation of the issue - * The location of the affected source code (tag/branch/commit or direct URL) - * Any special configuration required to reproduce the issue - * Step-by-step instructions to reproduce the issue - * Proof-of-concept or exploit code (if possible) - * Impact of the issue, including how an attacker might exploit the issue - -This information will help us triage your report more quickly. - -If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/opensource/security/bounty) page for more details about our active programs. - -## Preferred Languages - -We prefer all communications to be in English. - -## Policy - -Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/opensource/security/cvd). - - diff --git a/vendor/github.com/Microsoft/go-winio/backup.go b/vendor/github.com/Microsoft/go-winio/backup.go deleted file mode 100644 index b54341daa..000000000 --- a/vendor/github.com/Microsoft/go-winio/backup.go +++ /dev/null @@ -1,287 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "encoding/binary" - "errors" - "fmt" - "io" - "os" - "runtime" - "unicode/utf16" - - "github.com/Microsoft/go-winio/internal/fs" - "golang.org/x/sys/windows" -) - -//sys backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupRead -//sys backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) = BackupWrite - -const ( - BackupData = uint32(iota + 1) - BackupEaData - BackupSecurity - BackupAlternateData - BackupLink - BackupPropertyData - BackupObjectId //revive:disable-line:var-naming ID, not Id - BackupReparseData - BackupSparseBlock - BackupTxfsData -) - -const ( - StreamSparseAttributes = uint32(8) -) - -//nolint:revive // var-naming: ALL_CAPS -const ( - WRITE_DAC = windows.WRITE_DAC - WRITE_OWNER = windows.WRITE_OWNER - ACCESS_SYSTEM_SECURITY = windows.ACCESS_SYSTEM_SECURITY -) - -// BackupHeader represents a backup stream of a file. -type BackupHeader struct { - //revive:disable-next-line:var-naming ID, not Id - Id uint32 // The backup stream ID - Attributes uint32 // Stream attributes - Size int64 // The size of the stream in bytes - Name string // The name of the stream (for BackupAlternateData only). - Offset int64 // The offset of the stream in the file (for BackupSparseBlock only). -} - -type win32StreamID struct { - StreamID uint32 - Attributes uint32 - Size uint64 - NameSize uint32 -} - -// BackupStreamReader reads from a stream produced by the BackupRead Win32 API and produces a series -// of BackupHeader values. -type BackupStreamReader struct { - r io.Reader - bytesLeft int64 -} - -// NewBackupStreamReader produces a BackupStreamReader from any io.Reader. -func NewBackupStreamReader(r io.Reader) *BackupStreamReader { - return &BackupStreamReader{r, 0} -} - -// Next returns the next backup stream and prepares for calls to Read(). It skips the remainder of the current stream if -// it was not completely read. -func (r *BackupStreamReader) Next() (*BackupHeader, error) { - if r.bytesLeft > 0 { //nolint:nestif // todo: flatten this - if s, ok := r.r.(io.Seeker); ok { - // Make sure Seek on io.SeekCurrent sometimes succeeds - // before trying the actual seek. - if _, err := s.Seek(0, io.SeekCurrent); err == nil { - if _, err = s.Seek(r.bytesLeft, io.SeekCurrent); err != nil { - return nil, err - } - r.bytesLeft = 0 - } - } - if _, err := io.Copy(io.Discard, r); err != nil { - return nil, err - } - } - var wsi win32StreamID - if err := binary.Read(r.r, binary.LittleEndian, &wsi); err != nil { - return nil, err - } - hdr := &BackupHeader{ - Id: wsi.StreamID, - Attributes: wsi.Attributes, - Size: int64(wsi.Size), - } - if wsi.NameSize != 0 { - name := make([]uint16, int(wsi.NameSize/2)) - if err := binary.Read(r.r, binary.LittleEndian, name); err != nil { - return nil, err - } - hdr.Name = windows.UTF16ToString(name) - } - if wsi.StreamID == BackupSparseBlock { - if err := binary.Read(r.r, binary.LittleEndian, &hdr.Offset); err != nil { - return nil, err - } - hdr.Size -= 8 - } - r.bytesLeft = hdr.Size - return hdr, nil -} - -// Read reads from the current backup stream. -func (r *BackupStreamReader) Read(b []byte) (int, error) { - if r.bytesLeft == 0 { - return 0, io.EOF - } - if int64(len(b)) > r.bytesLeft { - b = b[:r.bytesLeft] - } - n, err := r.r.Read(b) - r.bytesLeft -= int64(n) - if err == io.EOF { - err = io.ErrUnexpectedEOF - } else if r.bytesLeft == 0 && err == nil { - err = io.EOF - } - return n, err -} - -// BackupStreamWriter writes a stream compatible with the BackupWrite Win32 API. -type BackupStreamWriter struct { - w io.Writer - bytesLeft int64 -} - -// NewBackupStreamWriter produces a BackupStreamWriter on top of an io.Writer. -func NewBackupStreamWriter(w io.Writer) *BackupStreamWriter { - return &BackupStreamWriter{w, 0} -} - -// WriteHeader writes the next backup stream header and prepares for calls to Write(). -func (w *BackupStreamWriter) WriteHeader(hdr *BackupHeader) error { - if w.bytesLeft != 0 { - return fmt.Errorf("missing %d bytes", w.bytesLeft) - } - name := utf16.Encode([]rune(hdr.Name)) - wsi := win32StreamID{ - StreamID: hdr.Id, - Attributes: hdr.Attributes, - Size: uint64(hdr.Size), - NameSize: uint32(len(name) * 2), - } - if hdr.Id == BackupSparseBlock { - // Include space for the int64 block offset - wsi.Size += 8 - } - if err := binary.Write(w.w, binary.LittleEndian, &wsi); err != nil { - return err - } - if len(name) != 0 { - if err := binary.Write(w.w, binary.LittleEndian, name); err != nil { - return err - } - } - if hdr.Id == BackupSparseBlock { - if err := binary.Write(w.w, binary.LittleEndian, hdr.Offset); err != nil { - return err - } - } - w.bytesLeft = hdr.Size - return nil -} - -// Write writes to the current backup stream. -func (w *BackupStreamWriter) Write(b []byte) (int, error) { - if w.bytesLeft < int64(len(b)) { - return 0, fmt.Errorf("too many bytes by %d", int64(len(b))-w.bytesLeft) - } - n, err := w.w.Write(b) - w.bytesLeft -= int64(n) - return n, err -} - -// BackupFileReader provides an io.ReadCloser interface on top of the BackupRead Win32 API. -type BackupFileReader struct { - f *os.File - includeSecurity bool - ctx uintptr -} - -// NewBackupFileReader returns a new BackupFileReader from a file handle. If includeSecurity is true, -// Read will attempt to read the security descriptor of the file. -func NewBackupFileReader(f *os.File, includeSecurity bool) *BackupFileReader { - r := &BackupFileReader{f, includeSecurity, 0} - return r -} - -// Read reads a backup stream from the file by calling the Win32 API BackupRead(). -func (r *BackupFileReader) Read(b []byte) (int, error) { - var bytesRead uint32 - err := backupRead(windows.Handle(r.f.Fd()), b, &bytesRead, false, r.includeSecurity, &r.ctx) - if err != nil { - return 0, &os.PathError{Op: "BackupRead", Path: r.f.Name(), Err: err} - } - runtime.KeepAlive(r.f) - if bytesRead == 0 { - return 0, io.EOF - } - return int(bytesRead), nil -} - -// Close frees Win32 resources associated with the BackupFileReader. It does not close -// the underlying file. -func (r *BackupFileReader) Close() error { - if r.ctx != 0 { - _ = backupRead(windows.Handle(r.f.Fd()), nil, nil, true, false, &r.ctx) - runtime.KeepAlive(r.f) - r.ctx = 0 - } - return nil -} - -// BackupFileWriter provides an io.WriteCloser interface on top of the BackupWrite Win32 API. -type BackupFileWriter struct { - f *os.File - includeSecurity bool - ctx uintptr -} - -// NewBackupFileWriter returns a new BackupFileWriter from a file handle. If includeSecurity is true, -// Write() will attempt to restore the security descriptor from the stream. -func NewBackupFileWriter(f *os.File, includeSecurity bool) *BackupFileWriter { - w := &BackupFileWriter{f, includeSecurity, 0} - return w -} - -// Write restores a portion of the file using the provided backup stream. -func (w *BackupFileWriter) Write(b []byte) (int, error) { - var bytesWritten uint32 - err := backupWrite(windows.Handle(w.f.Fd()), b, &bytesWritten, false, w.includeSecurity, &w.ctx) - if err != nil { - return 0, &os.PathError{Op: "BackupWrite", Path: w.f.Name(), Err: err} - } - runtime.KeepAlive(w.f) - if int(bytesWritten) != len(b) { - return int(bytesWritten), errors.New("not all bytes could be written") - } - return len(b), nil -} - -// Close frees Win32 resources associated with the BackupFileWriter. It does not -// close the underlying file. -func (w *BackupFileWriter) Close() error { - if w.ctx != 0 { - _ = backupWrite(windows.Handle(w.f.Fd()), nil, nil, true, false, &w.ctx) - runtime.KeepAlive(w.f) - w.ctx = 0 - } - return nil -} - -// OpenForBackup opens a file or directory, potentially skipping access checks if the backup -// or restore privileges have been acquired. -// -// If the file opened was a directory, it cannot be used with Readdir(). -func OpenForBackup(path string, access uint32, share uint32, createmode uint32) (*os.File, error) { - h, err := fs.CreateFile(path, - fs.AccessMask(access), - fs.FileShareMode(share), - nil, - fs.FileCreationDisposition(createmode), - fs.FILE_FLAG_BACKUP_SEMANTICS|fs.FILE_FLAG_OPEN_REPARSE_POINT, - 0, - ) - if err != nil { - err = &os.PathError{Op: "open", Path: path, Err: err} - return nil, err - } - return os.NewFile(uintptr(h), path), nil -} diff --git a/vendor/github.com/Microsoft/go-winio/doc.go b/vendor/github.com/Microsoft/go-winio/doc.go deleted file mode 100644 index 1f5bfe2d5..000000000 --- a/vendor/github.com/Microsoft/go-winio/doc.go +++ /dev/null @@ -1,22 +0,0 @@ -// This package provides utilities for efficiently performing Win32 IO operations in Go. -// Currently, this package is provides support for genreal IO and management of -// - named pipes -// - files -// - [Hyper-V sockets] -// -// This code is similar to Go's [net] package, and uses IO completion ports to avoid -// blocking IO on system threads, allowing Go to reuse the thread to schedule other goroutines. -// -// This limits support to Windows Vista and newer operating systems. -// -// Additionally, this package provides support for: -// - creating and managing GUIDs -// - writing to [ETW] -// - opening and manageing VHDs -// - parsing [Windows Image files] -// - auto-generating Win32 API code -// -// [Hyper-V sockets]: https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service -// [ETW]: https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/event-tracing-for-windows--etw- -// [Windows Image files]: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/work-with-windows-images -package winio diff --git a/vendor/github.com/Microsoft/go-winio/ea.go b/vendor/github.com/Microsoft/go-winio/ea.go deleted file mode 100644 index e104dbdfd..000000000 --- a/vendor/github.com/Microsoft/go-winio/ea.go +++ /dev/null @@ -1,137 +0,0 @@ -package winio - -import ( - "bytes" - "encoding/binary" - "errors" -) - -type fileFullEaInformation struct { - NextEntryOffset uint32 - Flags uint8 - NameLength uint8 - ValueLength uint16 -} - -var ( - fileFullEaInformationSize = binary.Size(&fileFullEaInformation{}) - - errInvalidEaBuffer = errors.New("invalid extended attribute buffer") - errEaNameTooLarge = errors.New("extended attribute name too large") - errEaValueTooLarge = errors.New("extended attribute value too large") -) - -// ExtendedAttribute represents a single Windows EA. -type ExtendedAttribute struct { - Name string - Value []byte - Flags uint8 -} - -func parseEa(b []byte) (ea ExtendedAttribute, nb []byte, err error) { - var info fileFullEaInformation - err = binary.Read(bytes.NewReader(b), binary.LittleEndian, &info) - if err != nil { - err = errInvalidEaBuffer - return ea, nb, err - } - - nameOffset := fileFullEaInformationSize - nameLen := int(info.NameLength) - valueOffset := nameOffset + int(info.NameLength) + 1 - valueLen := int(info.ValueLength) - nextOffset := int(info.NextEntryOffset) - if valueLen+valueOffset > len(b) || nextOffset < 0 || nextOffset > len(b) { - err = errInvalidEaBuffer - return ea, nb, err - } - - ea.Name = string(b[nameOffset : nameOffset+nameLen]) - ea.Value = b[valueOffset : valueOffset+valueLen] - ea.Flags = info.Flags - if info.NextEntryOffset != 0 { - nb = b[info.NextEntryOffset:] - } - return ea, nb, err -} - -// DecodeExtendedAttributes decodes a list of EAs from a FILE_FULL_EA_INFORMATION -// buffer retrieved from BackupRead, ZwQueryEaFile, etc. -func DecodeExtendedAttributes(b []byte) (eas []ExtendedAttribute, err error) { - for len(b) != 0 { - ea, nb, err := parseEa(b) - if err != nil { - return nil, err - } - - eas = append(eas, ea) - b = nb - } - return eas, err -} - -func writeEa(buf *bytes.Buffer, ea *ExtendedAttribute, last bool) error { - if int(uint8(len(ea.Name))) != len(ea.Name) { - return errEaNameTooLarge - } - if int(uint16(len(ea.Value))) != len(ea.Value) { - return errEaValueTooLarge - } - entrySize := uint32(fileFullEaInformationSize + len(ea.Name) + 1 + len(ea.Value)) - withPadding := (entrySize + 3) &^ 3 - nextOffset := uint32(0) - if !last { - nextOffset = withPadding - } - info := fileFullEaInformation{ - NextEntryOffset: nextOffset, - Flags: ea.Flags, - NameLength: uint8(len(ea.Name)), - ValueLength: uint16(len(ea.Value)), - } - - err := binary.Write(buf, binary.LittleEndian, &info) - if err != nil { - return err - } - - _, err = buf.Write([]byte(ea.Name)) - if err != nil { - return err - } - - err = buf.WriteByte(0) - if err != nil { - return err - } - - _, err = buf.Write(ea.Value) - if err != nil { - return err - } - - _, err = buf.Write([]byte{0, 0, 0}[0 : withPadding-entrySize]) - if err != nil { - return err - } - - return nil -} - -// EncodeExtendedAttributes encodes a list of EAs into a FILE_FULL_EA_INFORMATION -// buffer for use with BackupWrite, ZwSetEaFile, etc. -func EncodeExtendedAttributes(eas []ExtendedAttribute) ([]byte, error) { - var buf bytes.Buffer - for i := range eas { - last := false - if i == len(eas)-1 { - last = true - } - - err := writeEa(&buf, &eas[i], last) - if err != nil { - return nil, err - } - } - return buf.Bytes(), nil -} diff --git a/vendor/github.com/Microsoft/go-winio/file.go b/vendor/github.com/Microsoft/go-winio/file.go deleted file mode 100644 index fe82a180d..000000000 --- a/vendor/github.com/Microsoft/go-winio/file.go +++ /dev/null @@ -1,320 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "errors" - "io" - "runtime" - "sync" - "sync/atomic" - "syscall" - "time" - - "golang.org/x/sys/windows" -) - -//sys cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) = CancelIoEx -//sys createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) = CreateIoCompletionPort -//sys getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) = GetQueuedCompletionStatus -//sys setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) = SetFileCompletionNotificationModes -//sys wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) = ws2_32.WSAGetOverlappedResult - -var ( - ErrFileClosed = errors.New("file has already been closed") - ErrTimeout = &timeoutError{} -) - -type timeoutError struct{} - -func (*timeoutError) Error() string { return "i/o timeout" } -func (*timeoutError) Timeout() bool { return true } -func (*timeoutError) Temporary() bool { return true } - -type timeoutChan chan struct{} - -var ioInitOnce sync.Once -var ioCompletionPort windows.Handle - -// ioResult contains the result of an asynchronous IO operation. -type ioResult struct { - bytes uint32 - err error -} - -// ioOperation represents an outstanding asynchronous Win32 IO. -type ioOperation struct { - o windows.Overlapped - ch chan ioResult -} - -func initIO() { - h, err := createIoCompletionPort(windows.InvalidHandle, 0, 0, 0xffffffff) - if err != nil { - panic(err) - } - ioCompletionPort = h - go ioCompletionProcessor(h) -} - -// win32File implements Reader, Writer, and Closer on a Win32 handle without blocking in a syscall. -// It takes ownership of this handle and will close it if it is garbage collected. -type win32File struct { - handle windows.Handle - wg sync.WaitGroup - wgLock sync.RWMutex - closing atomic.Bool - socket bool - readDeadline deadlineHandler - writeDeadline deadlineHandler -} - -type deadlineHandler struct { - setLock sync.Mutex - channel timeoutChan - channelLock sync.RWMutex - timer *time.Timer - timedout atomic.Bool -} - -// makeWin32File makes a new win32File from an existing file handle. -func makeWin32File(h windows.Handle) (*win32File, error) { - f := &win32File{handle: h} - ioInitOnce.Do(initIO) - _, err := createIoCompletionPort(h, ioCompletionPort, 0, 0xffffffff) - if err != nil { - return nil, err - } - err = setFileCompletionNotificationModes(h, windows.FILE_SKIP_COMPLETION_PORT_ON_SUCCESS|windows.FILE_SKIP_SET_EVENT_ON_HANDLE) - if err != nil { - return nil, err - } - f.readDeadline.channel = make(timeoutChan) - f.writeDeadline.channel = make(timeoutChan) - return f, nil -} - -// Deprecated: use NewOpenFile instead. -func MakeOpenFile(h syscall.Handle) (io.ReadWriteCloser, error) { - return NewOpenFile(windows.Handle(h)) -} - -func NewOpenFile(h windows.Handle) (io.ReadWriteCloser, error) { - // If we return the result of makeWin32File directly, it can result in an - // interface-wrapped nil, rather than a nil interface value. - f, err := makeWin32File(h) - if err != nil { - return nil, err - } - return f, nil -} - -// closeHandle closes the resources associated with a Win32 handle. -func (f *win32File) closeHandle() { - f.wgLock.Lock() - // Atomically set that we are closing, releasing the resources only once. - if !f.closing.Swap(true) { - f.wgLock.Unlock() - // cancel all IO and wait for it to complete - _ = cancelIoEx(f.handle, nil) - f.wg.Wait() - // at this point, no new IO can start - windows.Close(f.handle) - f.handle = 0 - } else { - f.wgLock.Unlock() - } -} - -// Close closes a win32File. -func (f *win32File) Close() error { - f.closeHandle() - return nil -} - -// IsClosed checks if the file has been closed. -func (f *win32File) IsClosed() bool { - return f.closing.Load() -} - -// prepareIO prepares for a new IO operation. -// The caller must call f.wg.Done() when the IO is finished, prior to Close() returning. -func (f *win32File) prepareIO() (*ioOperation, error) { - f.wgLock.RLock() - if f.closing.Load() { - f.wgLock.RUnlock() - return nil, ErrFileClosed - } - f.wg.Add(1) - f.wgLock.RUnlock() - c := &ioOperation{} - c.ch = make(chan ioResult) - return c, nil -} - -// ioCompletionProcessor processes completed async IOs forever. -func ioCompletionProcessor(h windows.Handle) { - for { - var bytes uint32 - var key uintptr - var op *ioOperation - err := getQueuedCompletionStatus(h, &bytes, &key, &op, windows.INFINITE) - if op == nil { - panic(err) - } - op.ch <- ioResult{bytes, err} - } -} - -// todo: helsaawy - create an asyncIO version that takes a context - -// asyncIO processes the return value from ReadFile or WriteFile, blocking until -// the operation has actually completed. -func (f *win32File) asyncIO(c *ioOperation, d *deadlineHandler, bytes uint32, err error) (int, error) { - if err != windows.ERROR_IO_PENDING { //nolint:errorlint // err is Errno - return int(bytes), err - } - - if f.closing.Load() { - _ = cancelIoEx(f.handle, &c.o) - } - - var timeout timeoutChan - if d != nil { - d.channelLock.Lock() - timeout = d.channel - d.channelLock.Unlock() - } - - var r ioResult - select { - case r = <-c.ch: - err = r.err - if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno - if f.closing.Load() { - err = ErrFileClosed - } - } else if err != nil && f.socket { - // err is from Win32. Query the overlapped structure to get the winsock error. - var bytes, flags uint32 - err = wsaGetOverlappedResult(f.handle, &c.o, &bytes, false, &flags) - } - case <-timeout: - _ = cancelIoEx(f.handle, &c.o) - r = <-c.ch - err = r.err - if err == windows.ERROR_OPERATION_ABORTED { //nolint:errorlint // err is Errno - err = ErrTimeout - } - } - - // runtime.KeepAlive is needed, as c is passed via native - // code to ioCompletionProcessor, c must remain alive - // until the channel read is complete. - // todo: (de)allocate *ioOperation via win32 heap functions, instead of needing to KeepAlive? - runtime.KeepAlive(c) - return int(r.bytes), err -} - -// Read reads from a file handle. -func (f *win32File) Read(b []byte) (int, error) { - c, err := f.prepareIO() - if err != nil { - return 0, err - } - defer f.wg.Done() - - if f.readDeadline.timedout.Load() { - return 0, ErrTimeout - } - - var bytes uint32 - err = windows.ReadFile(f.handle, b, &bytes, &c.o) - n, err := f.asyncIO(c, &f.readDeadline, bytes, err) - runtime.KeepAlive(b) - - // Handle EOF conditions. - if err == nil && n == 0 && len(b) != 0 { - return 0, io.EOF - } else if err == windows.ERROR_BROKEN_PIPE { //nolint:errorlint // err is Errno - return 0, io.EOF - } - return n, err -} - -// Write writes to a file handle. -func (f *win32File) Write(b []byte) (int, error) { - c, err := f.prepareIO() - if err != nil { - return 0, err - } - defer f.wg.Done() - - if f.writeDeadline.timedout.Load() { - return 0, ErrTimeout - } - - var bytes uint32 - err = windows.WriteFile(f.handle, b, &bytes, &c.o) - n, err := f.asyncIO(c, &f.writeDeadline, bytes, err) - runtime.KeepAlive(b) - return n, err -} - -func (f *win32File) SetReadDeadline(deadline time.Time) error { - return f.readDeadline.set(deadline) -} - -func (f *win32File) SetWriteDeadline(deadline time.Time) error { - return f.writeDeadline.set(deadline) -} - -func (f *win32File) Flush() error { - return windows.FlushFileBuffers(f.handle) -} - -func (f *win32File) Fd() uintptr { - return uintptr(f.handle) -} - -func (d *deadlineHandler) set(deadline time.Time) error { - d.setLock.Lock() - defer d.setLock.Unlock() - - if d.timer != nil { - if !d.timer.Stop() { - <-d.channel - } - d.timer = nil - } - d.timedout.Store(false) - - select { - case <-d.channel: - d.channelLock.Lock() - d.channel = make(chan struct{}) - d.channelLock.Unlock() - default: - } - - if deadline.IsZero() { - return nil - } - - timeoutIO := func() { - d.timedout.Store(true) - close(d.channel) - } - - now := time.Now() - duration := deadline.Sub(now) - if deadline.After(now) { - // Deadline is in the future, set a timer to wait - d.timer = time.AfterFunc(duration, timeoutIO) - } else { - // Deadline is in the past. Cancel all pending IO now. - timeoutIO() - } - return nil -} diff --git a/vendor/github.com/Microsoft/go-winio/fileinfo.go b/vendor/github.com/Microsoft/go-winio/fileinfo.go deleted file mode 100644 index c860eb991..000000000 --- a/vendor/github.com/Microsoft/go-winio/fileinfo.go +++ /dev/null @@ -1,106 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "os" - "runtime" - "unsafe" - - "golang.org/x/sys/windows" -) - -// FileBasicInfo contains file access time and file attributes information. -type FileBasicInfo struct { - CreationTime, LastAccessTime, LastWriteTime, ChangeTime windows.Filetime - FileAttributes uint32 - _ uint32 // padding -} - -// alignedFileBasicInfo is a FileBasicInfo, but aligned to uint64 by containing -// uint64 rather than windows.Filetime. Filetime contains two uint32s. uint64 -// alignment is necessary to pass this as FILE_BASIC_INFO. -type alignedFileBasicInfo struct { - CreationTime, LastAccessTime, LastWriteTime, ChangeTime uint64 - FileAttributes uint32 - _ uint32 // padding -} - -// GetFileBasicInfo retrieves times and attributes for a file. -func GetFileBasicInfo(f *os.File) (*FileBasicInfo, error) { - bi := &alignedFileBasicInfo{} - if err := windows.GetFileInformationByHandleEx( - windows.Handle(f.Fd()), - windows.FileBasicInfo, - (*byte)(unsafe.Pointer(bi)), - uint32(unsafe.Sizeof(*bi)), - ); err != nil { - return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} - } - runtime.KeepAlive(f) - // Reinterpret the alignedFileBasicInfo as a FileBasicInfo so it matches the - // public API of this module. The data may be unnecessarily aligned. - return (*FileBasicInfo)(unsafe.Pointer(bi)), nil -} - -// SetFileBasicInfo sets times and attributes for a file. -func SetFileBasicInfo(f *os.File, bi *FileBasicInfo) error { - // Create an alignedFileBasicInfo based on a FileBasicInfo. The copy is - // suitable to pass to GetFileInformationByHandleEx. - biAligned := *(*alignedFileBasicInfo)(unsafe.Pointer(bi)) - if err := windows.SetFileInformationByHandle( - windows.Handle(f.Fd()), - windows.FileBasicInfo, - (*byte)(unsafe.Pointer(&biAligned)), - uint32(unsafe.Sizeof(biAligned)), - ); err != nil { - return &os.PathError{Op: "SetFileInformationByHandle", Path: f.Name(), Err: err} - } - runtime.KeepAlive(f) - return nil -} - -// FileStandardInfo contains extended information for the file. -// FILE_STANDARD_INFO in WinBase.h -// https://docs.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-file_standard_info -type FileStandardInfo struct { - AllocationSize, EndOfFile int64 - NumberOfLinks uint32 - DeletePending, Directory bool -} - -// GetFileStandardInfo retrieves ended information for the file. -func GetFileStandardInfo(f *os.File) (*FileStandardInfo, error) { - si := &FileStandardInfo{} - if err := windows.GetFileInformationByHandleEx(windows.Handle(f.Fd()), - windows.FileStandardInfo, - (*byte)(unsafe.Pointer(si)), - uint32(unsafe.Sizeof(*si))); err != nil { - return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} - } - runtime.KeepAlive(f) - return si, nil -} - -// FileIDInfo contains the volume serial number and file ID for a file. This pair should be -// unique on a system. -type FileIDInfo struct { - VolumeSerialNumber uint64 - FileID [16]byte -} - -// GetFileID retrieves the unique (volume, file ID) pair for a file. -func GetFileID(f *os.File) (*FileIDInfo, error) { - fileID := &FileIDInfo{} - if err := windows.GetFileInformationByHandleEx( - windows.Handle(f.Fd()), - windows.FileIdInfo, - (*byte)(unsafe.Pointer(fileID)), - uint32(unsafe.Sizeof(*fileID)), - ); err != nil { - return nil, &os.PathError{Op: "GetFileInformationByHandleEx", Path: f.Name(), Err: err} - } - runtime.KeepAlive(f) - return fileID, nil -} diff --git a/vendor/github.com/Microsoft/go-winio/hvsock.go b/vendor/github.com/Microsoft/go-winio/hvsock.go deleted file mode 100644 index c4fdd9d4a..000000000 --- a/vendor/github.com/Microsoft/go-winio/hvsock.go +++ /dev/null @@ -1,582 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "context" - "errors" - "fmt" - "io" - "net" - "os" - "time" - "unsafe" - - "golang.org/x/sys/windows" - - "github.com/Microsoft/go-winio/internal/socket" - "github.com/Microsoft/go-winio/pkg/guid" -) - -const afHVSock = 34 // AF_HYPERV - -// Well known Service and VM IDs -// https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/make-integration-service#vmid-wildcards - -// HvsockGUIDWildcard is the wildcard VmId for accepting connections from all partitions. -func HvsockGUIDWildcard() guid.GUID { // 00000000-0000-0000-0000-000000000000 - return guid.GUID{} -} - -// HvsockGUIDBroadcast is the wildcard VmId for broadcasting sends to all partitions. -func HvsockGUIDBroadcast() guid.GUID { // ffffffff-ffff-ffff-ffff-ffffffffffff - return guid.GUID{ - Data1: 0xffffffff, - Data2: 0xffff, - Data3: 0xffff, - Data4: [8]uint8{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, - } -} - -// HvsockGUIDLoopback is the Loopback VmId for accepting connections to the same partition as the connector. -func HvsockGUIDLoopback() guid.GUID { // e0e16197-dd56-4a10-9195-5ee7a155a838 - return guid.GUID{ - Data1: 0xe0e16197, - Data2: 0xdd56, - Data3: 0x4a10, - Data4: [8]uint8{0x91, 0x95, 0x5e, 0xe7, 0xa1, 0x55, 0xa8, 0x38}, - } -} - -// HvsockGUIDSiloHost is the address of a silo's host partition: -// - The silo host of a hosted silo is the utility VM. -// - The silo host of a silo on a physical host is the physical host. -func HvsockGUIDSiloHost() guid.GUID { // 36bd0c5c-7276-4223-88ba-7d03b654c568 - return guid.GUID{ - Data1: 0x36bd0c5c, - Data2: 0x7276, - Data3: 0x4223, - Data4: [8]byte{0x88, 0xba, 0x7d, 0x03, 0xb6, 0x54, 0xc5, 0x68}, - } -} - -// HvsockGUIDChildren is the wildcard VmId for accepting connections from the connector's child partitions. -func HvsockGUIDChildren() guid.GUID { // 90db8b89-0d35-4f79-8ce9-49ea0ac8b7cd - return guid.GUID{ - Data1: 0x90db8b89, - Data2: 0xd35, - Data3: 0x4f79, - Data4: [8]uint8{0x8c, 0xe9, 0x49, 0xea, 0xa, 0xc8, 0xb7, 0xcd}, - } -} - -// HvsockGUIDParent is the wildcard VmId for accepting connections from the connector's parent partition. -// Listening on this VmId accepts connection from: -// - Inside silos: silo host partition. -// - Inside hosted silo: host of the VM. -// - Inside VM: VM host. -// - Physical host: Not supported. -func HvsockGUIDParent() guid.GUID { // a42e7cda-d03f-480c-9cc2-a4de20abb878 - return guid.GUID{ - Data1: 0xa42e7cda, - Data2: 0xd03f, - Data3: 0x480c, - Data4: [8]uint8{0x9c, 0xc2, 0xa4, 0xde, 0x20, 0xab, 0xb8, 0x78}, - } -} - -// hvsockVsockServiceTemplate is the Service GUID used for the VSOCK protocol. -func hvsockVsockServiceTemplate() guid.GUID { // 00000000-facb-11e6-bd58-64006a7986d3 - return guid.GUID{ - Data2: 0xfacb, - Data3: 0x11e6, - Data4: [8]uint8{0xbd, 0x58, 0x64, 0x00, 0x6a, 0x79, 0x86, 0xd3}, - } -} - -// An HvsockAddr is an address for a AF_HYPERV socket. -type HvsockAddr struct { - VMID guid.GUID - ServiceID guid.GUID -} - -type rawHvsockAddr struct { - Family uint16 - _ uint16 - VMID guid.GUID - ServiceID guid.GUID -} - -var _ socket.RawSockaddr = &rawHvsockAddr{} - -// Network returns the address's network name, "hvsock". -func (*HvsockAddr) Network() string { - return "hvsock" -} - -func (addr *HvsockAddr) String() string { - return fmt.Sprintf("%s:%s", &addr.VMID, &addr.ServiceID) -} - -// VsockServiceID returns an hvsock service ID corresponding to the specified AF_VSOCK port. -func VsockServiceID(port uint32) guid.GUID { - g := hvsockVsockServiceTemplate() // make a copy - g.Data1 = port - return g -} - -func (addr *HvsockAddr) raw() rawHvsockAddr { - return rawHvsockAddr{ - Family: afHVSock, - VMID: addr.VMID, - ServiceID: addr.ServiceID, - } -} - -func (addr *HvsockAddr) fromRaw(raw *rawHvsockAddr) { - addr.VMID = raw.VMID - addr.ServiceID = raw.ServiceID -} - -// Sockaddr returns a pointer to and the size of this struct. -// -// Implements the [socket.RawSockaddr] interface, and allows use in -// [socket.Bind] and [socket.ConnectEx]. -func (r *rawHvsockAddr) Sockaddr() (unsafe.Pointer, int32, error) { - return unsafe.Pointer(r), int32(unsafe.Sizeof(rawHvsockAddr{})), nil -} - -// Sockaddr interface allows use with `sockets.Bind()` and `.ConnectEx()`. -func (r *rawHvsockAddr) FromBytes(b []byte) error { - n := int(unsafe.Sizeof(rawHvsockAddr{})) - - if len(b) < n { - return fmt.Errorf("got %d, want %d: %w", len(b), n, socket.ErrBufferSize) - } - - copy(unsafe.Slice((*byte)(unsafe.Pointer(r)), n), b[:n]) - if r.Family != afHVSock { - return fmt.Errorf("got %d, want %d: %w", r.Family, afHVSock, socket.ErrAddrFamily) - } - - return nil -} - -// HvsockListener is a socket listener for the AF_HYPERV address family. -type HvsockListener struct { - sock *win32File - addr HvsockAddr -} - -var _ net.Listener = &HvsockListener{} - -// HvsockConn is a connected socket of the AF_HYPERV address family. -type HvsockConn struct { - sock *win32File - local, remote HvsockAddr -} - -var _ net.Conn = &HvsockConn{} - -func newHVSocket() (*win32File, error) { - fd, err := windows.Socket(afHVSock, windows.SOCK_STREAM, 1) - if err != nil { - return nil, os.NewSyscallError("socket", err) - } - f, err := makeWin32File(fd) - if err != nil { - windows.Close(fd) - return nil, err - } - f.socket = true - return f, nil -} - -// ListenHvsock listens for connections on the specified hvsock address. -func ListenHvsock(addr *HvsockAddr) (_ *HvsockListener, err error) { - l := &HvsockListener{addr: *addr} - - var sock *win32File - sock, err = newHVSocket() - if err != nil { - return nil, l.opErr("listen", err) - } - defer func() { - if err != nil { - _ = sock.Close() - } - }() - - sa := addr.raw() - err = socket.Bind(sock.handle, &sa) - if err != nil { - return nil, l.opErr("listen", os.NewSyscallError("socket", err)) - } - err = windows.Listen(sock.handle, 16) - if err != nil { - return nil, l.opErr("listen", os.NewSyscallError("listen", err)) - } - return &HvsockListener{sock: sock, addr: *addr}, nil -} - -func (l *HvsockListener) opErr(op string, err error) error { - return &net.OpError{Op: op, Net: "hvsock", Addr: &l.addr, Err: err} -} - -// Addr returns the listener's network address. -func (l *HvsockListener) Addr() net.Addr { - return &l.addr -} - -// Accept waits for the next connection and returns it. -func (l *HvsockListener) Accept() (_ net.Conn, err error) { - sock, err := newHVSocket() - if err != nil { - return nil, l.opErr("accept", err) - } - defer func() { - if sock != nil { - sock.Close() - } - }() - c, err := l.sock.prepareIO() - if err != nil { - return nil, l.opErr("accept", err) - } - defer l.sock.wg.Done() - - // AcceptEx, per documentation, requires an extra 16 bytes per address. - // - // https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex - const addrlen = uint32(16 + unsafe.Sizeof(rawHvsockAddr{})) - var addrbuf [addrlen * 2]byte - - var bytes uint32 - err = windows.AcceptEx(l.sock.handle, sock.handle, &addrbuf[0], 0 /* rxdatalen */, addrlen, addrlen, &bytes, &c.o) - if _, err = l.sock.asyncIO(c, nil, bytes, err); err != nil { - return nil, l.opErr("accept", os.NewSyscallError("acceptex", err)) - } - - conn := &HvsockConn{ - sock: sock, - } - // The local address returned in the AcceptEx buffer is the same as the Listener socket's - // address. However, the service GUID reported by GetSockName is different from the Listeners - // socket, and is sometimes the same as the local address of the socket that dialed the - // address, with the service GUID.Data1 incremented, but othertimes is different. - // todo: does the local address matter? is the listener's address or the actual address appropriate? - conn.local.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[0]))) - conn.remote.fromRaw((*rawHvsockAddr)(unsafe.Pointer(&addrbuf[addrlen]))) - - // initialize the accepted socket and update its properties with those of the listening socket - if err = windows.Setsockopt(sock.handle, - windows.SOL_SOCKET, windows.SO_UPDATE_ACCEPT_CONTEXT, - (*byte)(unsafe.Pointer(&l.sock.handle)), int32(unsafe.Sizeof(l.sock.handle))); err != nil { - return nil, conn.opErr("accept", os.NewSyscallError("setsockopt", err)) - } - - sock = nil - return conn, nil -} - -// Close closes the listener, causing any pending Accept calls to fail. -func (l *HvsockListener) Close() error { - return l.sock.Close() -} - -// HvsockDialer configures and dials a Hyper-V Socket (ie, [HvsockConn]). -type HvsockDialer struct { - // Deadline is the time the Dial operation must connect before erroring. - Deadline time.Time - - // Retries is the number of additional connects to try if the connection times out, is refused, - // or the host is unreachable - Retries uint - - // RetryWait is the time to wait after a connection error to retry - RetryWait time.Duration - - rt *time.Timer // redial wait timer -} - -// Dial the Hyper-V socket at addr. -// -// See [HvsockDialer.Dial] for more information. -func Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) { - return (&HvsockDialer{}).Dial(ctx, addr) -} - -// Dial attempts to connect to the Hyper-V socket at addr, and returns a connection if successful. -// Will attempt (HvsockDialer).Retries if dialing fails, waiting (HvsockDialer).RetryWait between -// retries. -// -// Dialing can be cancelled either by providing (HvsockDialer).Deadline, or cancelling ctx. -func (d *HvsockDialer) Dial(ctx context.Context, addr *HvsockAddr) (conn *HvsockConn, err error) { - op := "dial" - // create the conn early to use opErr() - conn = &HvsockConn{ - remote: *addr, - } - - if !d.Deadline.IsZero() { - var cancel context.CancelFunc - ctx, cancel = context.WithDeadline(ctx, d.Deadline) - defer cancel() - } - - // preemptive timeout/cancellation check - if err = ctx.Err(); err != nil { - return nil, conn.opErr(op, err) - } - - sock, err := newHVSocket() - if err != nil { - return nil, conn.opErr(op, err) - } - defer func() { - if sock != nil { - sock.Close() - } - }() - - sa := addr.raw() - err = socket.Bind(sock.handle, &sa) - if err != nil { - return nil, conn.opErr(op, os.NewSyscallError("bind", err)) - } - - c, err := sock.prepareIO() - if err != nil { - return nil, conn.opErr(op, err) - } - defer sock.wg.Done() - var bytes uint32 - for i := uint(0); i <= d.Retries; i++ { - err = socket.ConnectEx( - sock.handle, - &sa, - nil, // sendBuf - 0, // sendDataLen - &bytes, - (*windows.Overlapped)(unsafe.Pointer(&c.o))) - _, err = sock.asyncIO(c, nil, bytes, err) - if i < d.Retries && canRedial(err) { - if err = d.redialWait(ctx); err == nil { - continue - } - } - break - } - if err != nil { - return nil, conn.opErr(op, os.NewSyscallError("connectex", err)) - } - - // update the connection properties, so shutdown can be used - if err = windows.Setsockopt( - sock.handle, - windows.SOL_SOCKET, - windows.SO_UPDATE_CONNECT_CONTEXT, - nil, // optvalue - 0, // optlen - ); err != nil { - return nil, conn.opErr(op, os.NewSyscallError("setsockopt", err)) - } - - // get the local name - var sal rawHvsockAddr - err = socket.GetSockName(sock.handle, &sal) - if err != nil { - return nil, conn.opErr(op, os.NewSyscallError("getsockname", err)) - } - conn.local.fromRaw(&sal) - - // one last check for timeout, since asyncIO doesn't check the context - if err = ctx.Err(); err != nil { - return nil, conn.opErr(op, err) - } - - conn.sock = sock - sock = nil - - return conn, nil -} - -// redialWait waits before attempting to redial, resetting the timer as appropriate. -func (d *HvsockDialer) redialWait(ctx context.Context) (err error) { - if d.RetryWait == 0 { - return nil - } - - if d.rt == nil { - d.rt = time.NewTimer(d.RetryWait) - } else { - // should already be stopped and drained - d.rt.Reset(d.RetryWait) - } - - select { - case <-ctx.Done(): - case <-d.rt.C: - return nil - } - - // stop and drain the timer - if !d.rt.Stop() { - <-d.rt.C - } - return ctx.Err() -} - -// assumes error is a plain, unwrapped windows.Errno provided by direct syscall. -func canRedial(err error) bool { - //nolint:errorlint // guaranteed to be an Errno - switch err { - case windows.WSAECONNREFUSED, windows.WSAENETUNREACH, windows.WSAETIMEDOUT, - windows.ERROR_CONNECTION_REFUSED, windows.ERROR_CONNECTION_UNAVAIL: - return true - default: - return false - } -} - -func (conn *HvsockConn) opErr(op string, err error) error { - // translate from "file closed" to "socket closed" - if errors.Is(err, ErrFileClosed) { - err = socket.ErrSocketClosed - } - return &net.OpError{Op: op, Net: "hvsock", Source: &conn.local, Addr: &conn.remote, Err: err} -} - -func (conn *HvsockConn) Read(b []byte) (int, error) { - c, err := conn.sock.prepareIO() - if err != nil { - return 0, conn.opErr("read", err) - } - defer conn.sock.wg.Done() - buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))} - var flags, bytes uint32 - err = windows.WSARecv(conn.sock.handle, &buf, 1, &bytes, &flags, &c.o, nil) - n, err := conn.sock.asyncIO(c, &conn.sock.readDeadline, bytes, err) - if err != nil { - var eno windows.Errno - if errors.As(err, &eno) { - err = os.NewSyscallError("wsarecv", eno) - } - return 0, conn.opErr("read", err) - } else if n == 0 { - err = io.EOF - } - return n, err -} - -func (conn *HvsockConn) Write(b []byte) (int, error) { - t := 0 - for len(b) != 0 { - n, err := conn.write(b) - if err != nil { - return t + n, err - } - t += n - b = b[n:] - } - return t, nil -} - -func (conn *HvsockConn) write(b []byte) (int, error) { - c, err := conn.sock.prepareIO() - if err != nil { - return 0, conn.opErr("write", err) - } - defer conn.sock.wg.Done() - buf := windows.WSABuf{Buf: &b[0], Len: uint32(len(b))} - var bytes uint32 - err = windows.WSASend(conn.sock.handle, &buf, 1, &bytes, 0, &c.o, nil) - n, err := conn.sock.asyncIO(c, &conn.sock.writeDeadline, bytes, err) - if err != nil { - var eno windows.Errno - if errors.As(err, &eno) { - err = os.NewSyscallError("wsasend", eno) - } - return 0, conn.opErr("write", err) - } - return n, err -} - -// Close closes the socket connection, failing any pending read or write calls. -func (conn *HvsockConn) Close() error { - return conn.sock.Close() -} - -func (conn *HvsockConn) IsClosed() bool { - return conn.sock.IsClosed() -} - -// shutdown disables sending or receiving on a socket. -func (conn *HvsockConn) shutdown(how int) error { - if conn.IsClosed() { - return socket.ErrSocketClosed - } - - err := windows.Shutdown(conn.sock.handle, how) - if err != nil { - // If the connection was closed, shutdowns fail with "not connected" - if errors.Is(err, windows.WSAENOTCONN) || - errors.Is(err, windows.WSAESHUTDOWN) { - err = socket.ErrSocketClosed - } - return os.NewSyscallError("shutdown", err) - } - return nil -} - -// CloseRead shuts down the read end of the socket, preventing future read operations. -func (conn *HvsockConn) CloseRead() error { - err := conn.shutdown(windows.SHUT_RD) - if err != nil { - return conn.opErr("closeread", err) - } - return nil -} - -// CloseWrite shuts down the write end of the socket, preventing future write operations and -// notifying the other endpoint that no more data will be written. -func (conn *HvsockConn) CloseWrite() error { - err := conn.shutdown(windows.SHUT_WR) - if err != nil { - return conn.opErr("closewrite", err) - } - return nil -} - -// LocalAddr returns the local address of the connection. -func (conn *HvsockConn) LocalAddr() net.Addr { - return &conn.local -} - -// RemoteAddr returns the remote address of the connection. -func (conn *HvsockConn) RemoteAddr() net.Addr { - return &conn.remote -} - -// SetDeadline implements the net.Conn SetDeadline method. -func (conn *HvsockConn) SetDeadline(t time.Time) error { - // todo: implement `SetDeadline` for `win32File` - if err := conn.SetReadDeadline(t); err != nil { - return fmt.Errorf("set read deadline: %w", err) - } - if err := conn.SetWriteDeadline(t); err != nil { - return fmt.Errorf("set write deadline: %w", err) - } - return nil -} - -// SetReadDeadline implements the net.Conn SetReadDeadline method. -func (conn *HvsockConn) SetReadDeadline(t time.Time) error { - return conn.sock.SetReadDeadline(t) -} - -// SetWriteDeadline implements the net.Conn SetWriteDeadline method. -func (conn *HvsockConn) SetWriteDeadline(t time.Time) error { - return conn.sock.SetWriteDeadline(t) -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go b/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go deleted file mode 100644 index 1f6538817..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/fs/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// This package contains Win32 filesystem functionality. -package fs diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go b/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go deleted file mode 100644 index 0cd9621df..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/fs/fs.go +++ /dev/null @@ -1,262 +0,0 @@ -//go:build windows - -package fs - -import ( - "golang.org/x/sys/windows" - - "github.com/Microsoft/go-winio/internal/stringbuffer" -) - -//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go fs.go - -// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew -//sys CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateFileW - -const NullHandle windows.Handle = 0 - -// AccessMask defines standard, specific, and generic rights. -// -// Used with CreateFile and NtCreateFile (and co.). -// -// Bitmask: -// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 -// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -// +---------------+---------------+-------------------------------+ -// |G|G|G|G|Resvd|A| StandardRights| SpecificRights | -// |R|W|E|A| |S| | | -// +-+-------------+---------------+-------------------------------+ -// -// GR Generic Read -// GW Generic Write -// GE Generic Exectue -// GA Generic All -// Resvd Reserved -// AS Access Security System -// -// https://learn.microsoft.com/en-us/windows/win32/secauthz/access-mask -// -// https://learn.microsoft.com/en-us/windows/win32/secauthz/generic-access-rights -// -// https://learn.microsoft.com/en-us/windows/win32/fileio/file-access-rights-constants -type AccessMask = windows.ACCESS_MASK - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - // Not actually any. - // - // For CreateFile: "query certain metadata such as file, directory, or device attributes without accessing that file or device" - // https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilew#parameters - FILE_ANY_ACCESS AccessMask = 0 - - GENERIC_READ AccessMask = 0x8000_0000 - GENERIC_WRITE AccessMask = 0x4000_0000 - GENERIC_EXECUTE AccessMask = 0x2000_0000 - GENERIC_ALL AccessMask = 0x1000_0000 - ACCESS_SYSTEM_SECURITY AccessMask = 0x0100_0000 - - // Specific Object Access - // from ntioapi.h - - FILE_READ_DATA AccessMask = (0x0001) // file & pipe - FILE_LIST_DIRECTORY AccessMask = (0x0001) // directory - - FILE_WRITE_DATA AccessMask = (0x0002) // file & pipe - FILE_ADD_FILE AccessMask = (0x0002) // directory - - FILE_APPEND_DATA AccessMask = (0x0004) // file - FILE_ADD_SUBDIRECTORY AccessMask = (0x0004) // directory - FILE_CREATE_PIPE_INSTANCE AccessMask = (0x0004) // named pipe - - FILE_READ_EA AccessMask = (0x0008) // file & directory - FILE_READ_PROPERTIES AccessMask = FILE_READ_EA - - FILE_WRITE_EA AccessMask = (0x0010) // file & directory - FILE_WRITE_PROPERTIES AccessMask = FILE_WRITE_EA - - FILE_EXECUTE AccessMask = (0x0020) // file - FILE_TRAVERSE AccessMask = (0x0020) // directory - - FILE_DELETE_CHILD AccessMask = (0x0040) // directory - - FILE_READ_ATTRIBUTES AccessMask = (0x0080) // all - - FILE_WRITE_ATTRIBUTES AccessMask = (0x0100) // all - - FILE_ALL_ACCESS AccessMask = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF) - FILE_GENERIC_READ AccessMask = (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE) - FILE_GENERIC_WRITE AccessMask = (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE) - FILE_GENERIC_EXECUTE AccessMask = (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE) - - SPECIFIC_RIGHTS_ALL AccessMask = 0x0000FFFF - - // Standard Access - // from ntseapi.h - - DELETE AccessMask = 0x0001_0000 - READ_CONTROL AccessMask = 0x0002_0000 - WRITE_DAC AccessMask = 0x0004_0000 - WRITE_OWNER AccessMask = 0x0008_0000 - SYNCHRONIZE AccessMask = 0x0010_0000 - - STANDARD_RIGHTS_REQUIRED AccessMask = 0x000F_0000 - - STANDARD_RIGHTS_READ AccessMask = READ_CONTROL - STANDARD_RIGHTS_WRITE AccessMask = READ_CONTROL - STANDARD_RIGHTS_EXECUTE AccessMask = READ_CONTROL - - STANDARD_RIGHTS_ALL AccessMask = 0x001F_0000 -) - -type FileShareMode uint32 - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - FILE_SHARE_NONE FileShareMode = 0x00 - FILE_SHARE_READ FileShareMode = 0x01 - FILE_SHARE_WRITE FileShareMode = 0x02 - FILE_SHARE_DELETE FileShareMode = 0x04 - FILE_SHARE_VALID_FLAGS FileShareMode = 0x07 -) - -type FileCreationDisposition uint32 - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - // from winbase.h - - CREATE_NEW FileCreationDisposition = 0x01 - CREATE_ALWAYS FileCreationDisposition = 0x02 - OPEN_EXISTING FileCreationDisposition = 0x03 - OPEN_ALWAYS FileCreationDisposition = 0x04 - TRUNCATE_EXISTING FileCreationDisposition = 0x05 -) - -// Create disposition values for NtCreate* -type NTFileCreationDisposition uint32 - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - // From ntioapi.h - - FILE_SUPERSEDE NTFileCreationDisposition = 0x00 - FILE_OPEN NTFileCreationDisposition = 0x01 - FILE_CREATE NTFileCreationDisposition = 0x02 - FILE_OPEN_IF NTFileCreationDisposition = 0x03 - FILE_OVERWRITE NTFileCreationDisposition = 0x04 - FILE_OVERWRITE_IF NTFileCreationDisposition = 0x05 - FILE_MAXIMUM_DISPOSITION NTFileCreationDisposition = 0x05 -) - -// CreateFile and co. take flags or attributes together as one parameter. -// Define alias until we can use generics to allow both -// -// https://learn.microsoft.com/en-us/windows/win32/fileio/file-attribute-constants -type FileFlagOrAttribute uint32 - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - // from winnt.h - - FILE_FLAG_WRITE_THROUGH FileFlagOrAttribute = 0x8000_0000 - FILE_FLAG_OVERLAPPED FileFlagOrAttribute = 0x4000_0000 - FILE_FLAG_NO_BUFFERING FileFlagOrAttribute = 0x2000_0000 - FILE_FLAG_RANDOM_ACCESS FileFlagOrAttribute = 0x1000_0000 - FILE_FLAG_SEQUENTIAL_SCAN FileFlagOrAttribute = 0x0800_0000 - FILE_FLAG_DELETE_ON_CLOSE FileFlagOrAttribute = 0x0400_0000 - FILE_FLAG_BACKUP_SEMANTICS FileFlagOrAttribute = 0x0200_0000 - FILE_FLAG_POSIX_SEMANTICS FileFlagOrAttribute = 0x0100_0000 - FILE_FLAG_OPEN_REPARSE_POINT FileFlagOrAttribute = 0x0020_0000 - FILE_FLAG_OPEN_NO_RECALL FileFlagOrAttribute = 0x0010_0000 - FILE_FLAG_FIRST_PIPE_INSTANCE FileFlagOrAttribute = 0x0008_0000 -) - -// NtCreate* functions take a dedicated CreateOptions parameter. -// -// https://learn.microsoft.com/en-us/windows/win32/api/Winternl/nf-winternl-ntcreatefile -// -// https://learn.microsoft.com/en-us/windows/win32/devnotes/nt-create-named-pipe-file -type NTCreateOptions uint32 - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - // From ntioapi.h - - FILE_DIRECTORY_FILE NTCreateOptions = 0x0000_0001 - FILE_WRITE_THROUGH NTCreateOptions = 0x0000_0002 - FILE_SEQUENTIAL_ONLY NTCreateOptions = 0x0000_0004 - FILE_NO_INTERMEDIATE_BUFFERING NTCreateOptions = 0x0000_0008 - - FILE_SYNCHRONOUS_IO_ALERT NTCreateOptions = 0x0000_0010 - FILE_SYNCHRONOUS_IO_NONALERT NTCreateOptions = 0x0000_0020 - FILE_NON_DIRECTORY_FILE NTCreateOptions = 0x0000_0040 - FILE_CREATE_TREE_CONNECTION NTCreateOptions = 0x0000_0080 - - FILE_COMPLETE_IF_OPLOCKED NTCreateOptions = 0x0000_0100 - FILE_NO_EA_KNOWLEDGE NTCreateOptions = 0x0000_0200 - FILE_DISABLE_TUNNELING NTCreateOptions = 0x0000_0400 - FILE_RANDOM_ACCESS NTCreateOptions = 0x0000_0800 - - FILE_DELETE_ON_CLOSE NTCreateOptions = 0x0000_1000 - FILE_OPEN_BY_FILE_ID NTCreateOptions = 0x0000_2000 - FILE_OPEN_FOR_BACKUP_INTENT NTCreateOptions = 0x0000_4000 - FILE_NO_COMPRESSION NTCreateOptions = 0x0000_8000 -) - -type FileSQSFlag = FileFlagOrAttribute - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - // from winbase.h - - SECURITY_ANONYMOUS FileSQSFlag = FileSQSFlag(SecurityAnonymous << 16) - SECURITY_IDENTIFICATION FileSQSFlag = FileSQSFlag(SecurityIdentification << 16) - SECURITY_IMPERSONATION FileSQSFlag = FileSQSFlag(SecurityImpersonation << 16) - SECURITY_DELEGATION FileSQSFlag = FileSQSFlag(SecurityDelegation << 16) - - SECURITY_SQOS_PRESENT FileSQSFlag = 0x0010_0000 - SECURITY_VALID_SQOS_FLAGS FileSQSFlag = 0x001F_0000 -) - -// GetFinalPathNameByHandle flags -// -// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew#parameters -type GetFinalPathFlag uint32 - -//nolint:revive // SNAKE_CASE is not idiomatic in Go, but aligned with Win32 API. -const ( - GetFinalPathDefaultFlag GetFinalPathFlag = 0x0 - - FILE_NAME_NORMALIZED GetFinalPathFlag = 0x0 - FILE_NAME_OPENED GetFinalPathFlag = 0x8 - - VOLUME_NAME_DOS GetFinalPathFlag = 0x0 - VOLUME_NAME_GUID GetFinalPathFlag = 0x1 - VOLUME_NAME_NT GetFinalPathFlag = 0x2 - VOLUME_NAME_NONE GetFinalPathFlag = 0x4 -) - -// getFinalPathNameByHandle facilitates calling the Windows API GetFinalPathNameByHandle -// with the given handle and flags. It transparently takes care of creating a buffer of the -// correct size for the call. -// -// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfinalpathnamebyhandlew -func GetFinalPathNameByHandle(h windows.Handle, flags GetFinalPathFlag) (string, error) { - b := stringbuffer.NewWString() - //TODO: can loop infinitely if Win32 keeps returning the same (or a larger) n? - for { - n, err := windows.GetFinalPathNameByHandle(h, b.Pointer(), b.Cap(), uint32(flags)) - if err != nil { - return "", err - } - // If the buffer wasn't large enough, n will be the total size needed (including null terminator). - // Resize and try again. - if n > b.Cap() { - b.ResizeTo(n) - continue - } - // If the buffer is large enough, n will be the size not including the null terminator. - // Convert to a Go string and return. - return b.String(), nil - } -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/security.go b/vendor/github.com/Microsoft/go-winio/internal/fs/security.go deleted file mode 100644 index 81760ac67..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/fs/security.go +++ /dev/null @@ -1,12 +0,0 @@ -package fs - -// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-security_impersonation_level -type SecurityImpersonationLevel int32 // C default enums underlying type is `int`, which is Go `int32` - -// Impersonation levels -const ( - SecurityAnonymous SecurityImpersonationLevel = 0 - SecurityIdentification SecurityImpersonationLevel = 1 - SecurityImpersonation SecurityImpersonationLevel = 2 - SecurityDelegation SecurityImpersonationLevel = 3 -) diff --git a/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go deleted file mode 100644 index a94e234c7..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/fs/zsyscall_windows.go +++ /dev/null @@ -1,61 +0,0 @@ -//go:build windows - -// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT. - -package fs - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) - errERROR_EINVAL error = syscall.EINVAL -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return errERROR_EINVAL - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - return e -} - -var ( - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - - procCreateFileW = modkernel32.NewProc("CreateFileW") -) - -func CreateFile(name string, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _CreateFile(_p0, access, mode, sa, createmode, attrs, templatefile) -} - -func _CreateFile(name *uint16, access AccessMask, mode FileShareMode, sa *windows.SecurityAttributes, createmode FileCreationDisposition, attrs FileFlagOrAttribute, templatefile windows.Handle) (handle windows.Handle, err error) { - r0, _, e1 := syscall.SyscallN(procCreateFileW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(access), uintptr(mode), uintptr(unsafe.Pointer(sa)), uintptr(createmode), uintptr(attrs), uintptr(templatefile)) - handle = windows.Handle(r0) - if handle == windows.InvalidHandle { - err = errnoErr(e1) - } - return -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go b/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go deleted file mode 100644 index 7e82f9afa..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/socket/rawaddr.go +++ /dev/null @@ -1,20 +0,0 @@ -package socket - -import ( - "unsafe" -) - -// RawSockaddr allows structs to be used with [Bind] and [ConnectEx]. The -// struct must meet the Win32 sockaddr requirements specified here: -// https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2 -// -// Specifically, the struct size must be least larger than an int16 (unsigned short) -// for the address family. -type RawSockaddr interface { - // Sockaddr returns a pointer to the RawSockaddr and its struct size, allowing - // for the RawSockaddr's data to be overwritten by syscalls (if necessary). - // - // It is the callers responsibility to validate that the values are valid; invalid - // pointers or size can cause a panic. - Sockaddr() (unsafe.Pointer, int32, error) -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go b/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go deleted file mode 100644 index 88580d974..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/socket/socket.go +++ /dev/null @@ -1,177 +0,0 @@ -//go:build windows - -package socket - -import ( - "errors" - "fmt" - "net" - "sync" - "syscall" - "unsafe" - - "github.com/Microsoft/go-winio/pkg/guid" - "golang.org/x/sys/windows" -) - -//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go socket.go - -//sys getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getsockname -//sys getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) [failretval==socketError] = ws2_32.getpeername -//sys bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) [failretval==socketError] = ws2_32.bind - -const socketError = uintptr(^uint32(0)) - -var ( - // todo(helsaawy): create custom error types to store the desired vs actual size and addr family? - - ErrBufferSize = errors.New("buffer size") - ErrAddrFamily = errors.New("address family") - ErrInvalidPointer = errors.New("invalid pointer") - ErrSocketClosed = fmt.Errorf("socket closed: %w", net.ErrClosed) -) - -// todo(helsaawy): replace these with generics, ie: GetSockName[S RawSockaddr](s windows.Handle) (S, error) - -// GetSockName writes the local address of socket s to the [RawSockaddr] rsa. -// If rsa is not large enough, the [windows.WSAEFAULT] is returned. -func GetSockName(s windows.Handle, rsa RawSockaddr) error { - ptr, l, err := rsa.Sockaddr() - if err != nil { - return fmt.Errorf("could not retrieve socket pointer and size: %w", err) - } - - // although getsockname returns WSAEFAULT if the buffer is too small, it does not set - // &l to the correct size, so--apart from doubling the buffer repeatedly--there is no remedy - return getsockname(s, ptr, &l) -} - -// GetPeerName returns the remote address the socket is connected to. -// -// See [GetSockName] for more information. -func GetPeerName(s windows.Handle, rsa RawSockaddr) error { - ptr, l, err := rsa.Sockaddr() - if err != nil { - return fmt.Errorf("could not retrieve socket pointer and size: %w", err) - } - - return getpeername(s, ptr, &l) -} - -func Bind(s windows.Handle, rsa RawSockaddr) (err error) { - ptr, l, err := rsa.Sockaddr() - if err != nil { - return fmt.Errorf("could not retrieve socket pointer and size: %w", err) - } - - return bind(s, ptr, l) -} - -// "golang.org/x/sys/windows".ConnectEx and .Bind only accept internal implementations of the -// their sockaddr interface, so they cannot be used with HvsockAddr -// Replicate functionality here from -// https://cs.opensource.google/go/x/sys/+/master:windows/syscall_windows.go - -// The function pointers to `AcceptEx`, `ConnectEx` and `GetAcceptExSockaddrs` must be loaded at -// runtime via a WSAIoctl call: -// https://docs.microsoft.com/en-us/windows/win32/api/Mswsock/nc-mswsock-lpfn_connectex#remarks - -type runtimeFunc struct { - id guid.GUID - once sync.Once - addr uintptr - err error -} - -func (f *runtimeFunc) Load() error { - f.once.Do(func() { - var s windows.Handle - s, f.err = windows.Socket(windows.AF_INET, windows.SOCK_STREAM, windows.IPPROTO_TCP) - if f.err != nil { - return - } - defer windows.CloseHandle(s) //nolint:errcheck - - var n uint32 - f.err = windows.WSAIoctl(s, - windows.SIO_GET_EXTENSION_FUNCTION_POINTER, - (*byte)(unsafe.Pointer(&f.id)), - uint32(unsafe.Sizeof(f.id)), - (*byte)(unsafe.Pointer(&f.addr)), - uint32(unsafe.Sizeof(f.addr)), - &n, - nil, // overlapped - 0, // completionRoutine - ) - }) - return f.err -} - -var ( - // todo: add `AcceptEx` and `GetAcceptExSockaddrs` - WSAID_CONNECTEX = guid.GUID{ //revive:disable-line:var-naming ALL_CAPS - Data1: 0x25a207b9, - Data2: 0xddf3, - Data3: 0x4660, - Data4: [8]byte{0x8e, 0xe9, 0x76, 0xe5, 0x8c, 0x74, 0x06, 0x3e}, - } - - connectExFunc = runtimeFunc{id: WSAID_CONNECTEX} -) - -func ConnectEx( - fd windows.Handle, - rsa RawSockaddr, - sendBuf *byte, - sendDataLen uint32, - bytesSent *uint32, - overlapped *windows.Overlapped, -) error { - if err := connectExFunc.Load(); err != nil { - return fmt.Errorf("failed to load ConnectEx function pointer: %w", err) - } - ptr, n, err := rsa.Sockaddr() - if err != nil { - return err - } - return connectEx(fd, ptr, n, sendBuf, sendDataLen, bytesSent, overlapped) -} - -// BOOL LpfnConnectex( -// [in] SOCKET s, -// [in] const sockaddr *name, -// [in] int namelen, -// [in, optional] PVOID lpSendBuffer, -// [in] DWORD dwSendDataLength, -// [out] LPDWORD lpdwBytesSent, -// [in] LPOVERLAPPED lpOverlapped -// ) - -func connectEx( - s windows.Handle, - name unsafe.Pointer, - namelen int32, - sendBuf *byte, - sendDataLen uint32, - bytesSent *uint32, - overlapped *windows.Overlapped, -) (err error) { - r1, _, e1 := syscall.SyscallN(connectExFunc.addr, - uintptr(s), - uintptr(name), - uintptr(namelen), - uintptr(unsafe.Pointer(sendBuf)), - uintptr(sendDataLen), - uintptr(unsafe.Pointer(bytesSent)), - uintptr(unsafe.Pointer(overlapped)), - ) - - if r1 == 0 { - if e1 != 0 { - err = error(e1) - } else { - err = syscall.EINVAL - } - } - return err -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go deleted file mode 100644 index e1504126a..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/socket/zsyscall_windows.go +++ /dev/null @@ -1,69 +0,0 @@ -//go:build windows - -// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT. - -package socket - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) - errERROR_EINVAL error = syscall.EINVAL -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return errERROR_EINVAL - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - return e -} - -var ( - modws2_32 = windows.NewLazySystemDLL("ws2_32.dll") - - procbind = modws2_32.NewProc("bind") - procgetpeername = modws2_32.NewProc("getpeername") - procgetsockname = modws2_32.NewProc("getsockname") -) - -func bind(s windows.Handle, name unsafe.Pointer, namelen int32) (err error) { - r1, _, e1 := syscall.SyscallN(procbind.Addr(), uintptr(s), uintptr(name), uintptr(namelen)) - if r1 == socketError { - err = errnoErr(e1) - } - return -} - -func getpeername(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) { - r1, _, e1 := syscall.SyscallN(procgetpeername.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen))) - if r1 == socketError { - err = errnoErr(e1) - } - return -} - -func getsockname(s windows.Handle, name unsafe.Pointer, namelen *int32) (err error) { - r1, _, e1 := syscall.SyscallN(procgetsockname.Addr(), uintptr(s), uintptr(name), uintptr(unsafe.Pointer(namelen))) - if r1 == socketError { - err = errnoErr(e1) - } - return -} diff --git a/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go b/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go deleted file mode 100644 index 42ebc019f..000000000 --- a/vendor/github.com/Microsoft/go-winio/internal/stringbuffer/wstring.go +++ /dev/null @@ -1,132 +0,0 @@ -package stringbuffer - -import ( - "sync" - "unicode/utf16" -) - -// TODO: worth exporting and using in mkwinsyscall? - -// Uint16BufferSize is the buffer size in the pool, chosen somewhat arbitrarily to accommodate -// large path strings: -// MAX_PATH (260) + size of volume GUID prefix (49) + null terminator = 310. -const MinWStringCap = 310 - -// use *[]uint16 since []uint16 creates an extra allocation where the slice header -// is copied to heap and then referenced via pointer in the interface header that sync.Pool -// stores. -var pathPool = sync.Pool{ // if go1.18+ adds Pool[T], use that to store []uint16 directly - New: func() interface{} { - b := make([]uint16, MinWStringCap) - return &b - }, -} - -func newBuffer() []uint16 { return *(pathPool.Get().(*[]uint16)) } - -// freeBuffer copies the slice header data, and puts a pointer to that in the pool. -// This avoids taking a pointer to the slice header in WString, which can be set to nil. -func freeBuffer(b []uint16) { pathPool.Put(&b) } - -// WString is a wide string buffer ([]uint16) meant for storing UTF-16 encoded strings -// for interacting with Win32 APIs. -// Sizes are specified as uint32 and not int. -// -// It is not thread safe. -type WString struct { - // type-def allows casting to []uint16 directly, use struct to prevent that and allow adding fields in the future. - - // raw buffer - b []uint16 -} - -// NewWString returns a [WString] allocated from a shared pool with an -// initial capacity of at least [MinWStringCap]. -// Since the buffer may have been previously used, its contents are not guaranteed to be empty. -// -// The buffer should be freed via [WString.Free] -func NewWString() *WString { - return &WString{ - b: newBuffer(), - } -} - -func (b *WString) Free() { - if b.empty() { - return - } - freeBuffer(b.b) - b.b = nil -} - -// ResizeTo grows the buffer to at least c and returns the new capacity, freeing the -// previous buffer back into pool. -func (b *WString) ResizeTo(c uint32) uint32 { - // already sufficient (or n is 0) - if c <= b.Cap() { - return b.Cap() - } - - if c <= MinWStringCap { - c = MinWStringCap - } - // allocate at-least double buffer size, as is done in [bytes.Buffer] and other places - if c <= 2*b.Cap() { - c = 2 * b.Cap() - } - - b2 := make([]uint16, c) - if !b.empty() { - copy(b2, b.b) - freeBuffer(b.b) - } - b.b = b2 - return c -} - -// Buffer returns the underlying []uint16 buffer. -func (b *WString) Buffer() []uint16 { - if b.empty() { - return nil - } - return b.b -} - -// Pointer returns a pointer to the first uint16 in the buffer. -// If the [WString.Free] has already been called, the pointer will be nil. -func (b *WString) Pointer() *uint16 { - if b.empty() { - return nil - } - return &b.b[0] -} - -// String returns the returns the UTF-8 encoding of the UTF-16 string in the buffer. -// -// It assumes that the data is null-terminated. -func (b *WString) String() string { - // Using [windows.UTF16ToString] would require importing "golang.org/x/sys/windows" - // and would make this code Windows-only, which makes no sense. - // So copy UTF16ToString code into here. - // If other windows-specific code is added, switch to [windows.UTF16ToString] - - s := b.b - for i, v := range s { - if v == 0 { - s = s[:i] - break - } - } - return string(utf16.Decode(s)) -} - -// Cap returns the underlying buffer capacity. -func (b *WString) Cap() uint32 { - if b.empty() { - return 0 - } - return b.cap() -} - -func (b *WString) cap() uint32 { return uint32(cap(b.b)) } -func (b *WString) empty() bool { return b == nil || b.cap() == 0 } diff --git a/vendor/github.com/Microsoft/go-winio/pipe.go b/vendor/github.com/Microsoft/go-winio/pipe.go deleted file mode 100644 index a2da6639d..000000000 --- a/vendor/github.com/Microsoft/go-winio/pipe.go +++ /dev/null @@ -1,586 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "context" - "errors" - "fmt" - "io" - "net" - "os" - "runtime" - "time" - "unsafe" - - "golang.org/x/sys/windows" - - "github.com/Microsoft/go-winio/internal/fs" -) - -//sys connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) = ConnectNamedPipe -//sys createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) [failretval==windows.InvalidHandle] = CreateNamedPipeW -//sys disconnectNamedPipe(pipe windows.Handle) (err error) = DisconnectNamedPipe -//sys getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) = GetNamedPipeInfo -//sys getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) = GetNamedPipeHandleStateW -//sys ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) = ntdll.NtCreateNamedPipeFile -//sys rtlNtStatusToDosError(status ntStatus) (winerr error) = ntdll.RtlNtStatusToDosErrorNoTeb -//sys rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) = ntdll.RtlDosPathNameToNtPathName_U -//sys rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) = ntdll.RtlDefaultNpAcl - -type PipeConn interface { - net.Conn - Disconnect() error - Flush() error -} - -// type aliases for mkwinsyscall code -type ( - ntAccessMask = fs.AccessMask - ntFileShareMode = fs.FileShareMode - ntFileCreationDisposition = fs.NTFileCreationDisposition - ntFileOptions = fs.NTCreateOptions -) - -type ioStatusBlock struct { - Status, Information uintptr -} - -// typedef struct _OBJECT_ATTRIBUTES { -// ULONG Length; -// HANDLE RootDirectory; -// PUNICODE_STRING ObjectName; -// ULONG Attributes; -// PVOID SecurityDescriptor; -// PVOID SecurityQualityOfService; -// } OBJECT_ATTRIBUTES; -// -// https://learn.microsoft.com/en-us/windows/win32/api/ntdef/ns-ntdef-_object_attributes -type objectAttributes struct { - Length uintptr - RootDirectory uintptr - ObjectName *unicodeString - Attributes uintptr - SecurityDescriptor *securityDescriptor - SecurityQoS uintptr -} - -type unicodeString struct { - Length uint16 - MaximumLength uint16 - Buffer uintptr -} - -// typedef struct _SECURITY_DESCRIPTOR { -// BYTE Revision; -// BYTE Sbz1; -// SECURITY_DESCRIPTOR_CONTROL Control; -// PSID Owner; -// PSID Group; -// PACL Sacl; -// PACL Dacl; -// } SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR; -// -// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-security_descriptor -type securityDescriptor struct { - Revision byte - Sbz1 byte - Control uint16 - Owner uintptr - Group uintptr - Sacl uintptr //revive:disable-line:var-naming SACL, not Sacl - Dacl uintptr //revive:disable-line:var-naming DACL, not Dacl -} - -type ntStatus int32 - -func (status ntStatus) Err() error { - if status >= 0 { - return nil - } - return rtlNtStatusToDosError(status) -} - -var ( - // ErrPipeListenerClosed is returned for pipe operations on listeners that have been closed. - ErrPipeListenerClosed = net.ErrClosed - - errPipeWriteClosed = errors.New("pipe has been closed for write") -) - -type win32Pipe struct { - *win32File - path string -} - -var _ PipeConn = (*win32Pipe)(nil) - -type win32MessageBytePipe struct { - win32Pipe - writeClosed bool - readEOF bool -} - -type pipeAddress string - -func (f *win32Pipe) LocalAddr() net.Addr { - return pipeAddress(f.path) -} - -func (f *win32Pipe) RemoteAddr() net.Addr { - return pipeAddress(f.path) -} - -func (f *win32Pipe) SetDeadline(t time.Time) error { - if err := f.SetReadDeadline(t); err != nil { - return err - } - return f.SetWriteDeadline(t) -} - -func (f *win32Pipe) Disconnect() error { - return disconnectNamedPipe(f.win32File.handle) -} - -// CloseWrite closes the write side of a message pipe in byte mode. -func (f *win32MessageBytePipe) CloseWrite() error { - if f.writeClosed { - return errPipeWriteClosed - } - err := f.win32File.Flush() - if err != nil { - return err - } - _, err = f.win32File.Write(nil) - if err != nil { - return err - } - f.writeClosed = true - return nil -} - -// Write writes bytes to a message pipe in byte mode. Zero-byte writes are ignored, since -// they are used to implement CloseWrite(). -func (f *win32MessageBytePipe) Write(b []byte) (int, error) { - if f.writeClosed { - return 0, errPipeWriteClosed - } - if len(b) == 0 { - return 0, nil - } - return f.win32File.Write(b) -} - -// Read reads bytes from a message pipe in byte mode. A read of a zero-byte message on a message -// mode pipe will return io.EOF, as will all subsequent reads. -func (f *win32MessageBytePipe) Read(b []byte) (int, error) { - if f.readEOF { - return 0, io.EOF - } - n, err := f.win32File.Read(b) - if err == io.EOF { //nolint:errorlint - // If this was the result of a zero-byte read, then - // it is possible that the read was due to a zero-size - // message. Since we are simulating CloseWrite with a - // zero-byte message, ensure that all future Read() calls - // also return EOF. - f.readEOF = true - } else if err == windows.ERROR_MORE_DATA { //nolint:errorlint // err is Errno - // ERROR_MORE_DATA indicates that the pipe's read mode is message mode - // and the message still has more bytes. Treat this as a success, since - // this package presents all named pipes as byte streams. - err = nil - } - return n, err -} - -func (pipeAddress) Network() string { - return "pipe" -} - -func (s pipeAddress) String() string { - return string(s) -} - -// tryDialPipe attempts to dial the pipe at `path` until `ctx` cancellation or timeout. -func tryDialPipe(ctx context.Context, path *string, access fs.AccessMask, impLevel PipeImpLevel) (windows.Handle, error) { - for { - select { - case <-ctx.Done(): - return windows.Handle(0), ctx.Err() - default: - h, err := fs.CreateFile(*path, - access, - 0, // mode - nil, // security attributes - fs.OPEN_EXISTING, - fs.FILE_FLAG_OVERLAPPED|fs.SECURITY_SQOS_PRESENT|fs.FileSQSFlag(impLevel), - 0, // template file handle - ) - if err == nil { - return h, nil - } - if err != windows.ERROR_PIPE_BUSY { //nolint:errorlint // err is Errno - return h, &os.PathError{Err: err, Op: "open", Path: *path} - } - // Wait 10 msec and try again. This is a rather simplistic - // view, as we always try each 10 milliseconds. - time.Sleep(10 * time.Millisecond) - } - } -} - -// DialPipe connects to a named pipe by path, timing out if the connection -// takes longer than the specified duration. If timeout is nil, then we use -// a default timeout of 2 seconds. (We do not use WaitNamedPipe.) -func DialPipe(path string, timeout *time.Duration) (net.Conn, error) { - var absTimeout time.Time - if timeout != nil { - absTimeout = time.Now().Add(*timeout) - } else { - absTimeout = time.Now().Add(2 * time.Second) - } - ctx, cancel := context.WithDeadline(context.Background(), absTimeout) - defer cancel() - conn, err := DialPipeContext(ctx, path) - if errors.Is(err, context.DeadlineExceeded) { - return nil, ErrTimeout - } - return conn, err -} - -// DialPipeContext attempts to connect to a named pipe by `path` until `ctx` -// cancellation or timeout. -func DialPipeContext(ctx context.Context, path string) (net.Conn, error) { - return DialPipeAccess(ctx, path, uint32(fs.GENERIC_READ|fs.GENERIC_WRITE)) -} - -// PipeImpLevel is an enumeration of impersonation levels that may be set -// when calling DialPipeAccessImpersonation. -type PipeImpLevel uint32 - -const ( - PipeImpLevelAnonymous = PipeImpLevel(fs.SECURITY_ANONYMOUS) - PipeImpLevelIdentification = PipeImpLevel(fs.SECURITY_IDENTIFICATION) - PipeImpLevelImpersonation = PipeImpLevel(fs.SECURITY_IMPERSONATION) - PipeImpLevelDelegation = PipeImpLevel(fs.SECURITY_DELEGATION) -) - -// DialPipeAccess attempts to connect to a named pipe by `path` with `access` until `ctx` -// cancellation or timeout. -func DialPipeAccess(ctx context.Context, path string, access uint32) (net.Conn, error) { - return DialPipeAccessImpLevel(ctx, path, access, PipeImpLevelAnonymous) -} - -// DialPipeAccessImpLevel attempts to connect to a named pipe by `path` with -// `access` at `impLevel` until `ctx` cancellation or timeout. The other -// DialPipe* implementations use PipeImpLevelAnonymous. -func DialPipeAccessImpLevel(ctx context.Context, path string, access uint32, impLevel PipeImpLevel) (net.Conn, error) { - var err error - var h windows.Handle - h, err = tryDialPipe(ctx, &path, fs.AccessMask(access), impLevel) - if err != nil { - return nil, err - } - - var flags uint32 - err = getNamedPipeInfo(h, &flags, nil, nil, nil) - if err != nil { - return nil, err - } - - f, err := makeWin32File(h) - if err != nil { - windows.Close(h) - return nil, err - } - - // If the pipe is in message mode, return a message byte pipe, which - // supports CloseWrite(). - if flags&windows.PIPE_TYPE_MESSAGE != 0 { - return &win32MessageBytePipe{ - win32Pipe: win32Pipe{win32File: f, path: path}, - }, nil - } - return &win32Pipe{win32File: f, path: path}, nil -} - -type acceptResponse struct { - f *win32File - err error -} - -type win32PipeListener struct { - firstHandle windows.Handle - path string - config PipeConfig - acceptCh chan (chan acceptResponse) - closeCh chan int - doneCh chan int -} - -func makeServerPipeHandle(path string, sd []byte, c *PipeConfig, first bool) (windows.Handle, error) { - path16, err := windows.UTF16FromString(path) - if err != nil { - return 0, &os.PathError{Op: "open", Path: path, Err: err} - } - - var oa objectAttributes - oa.Length = unsafe.Sizeof(oa) - - var ntPath unicodeString - if err := rtlDosPathNameToNtPathName(&path16[0], - &ntPath, - 0, - 0, - ).Err(); err != nil { - return 0, &os.PathError{Op: "open", Path: path, Err: err} - } - defer windows.LocalFree(windows.Handle(ntPath.Buffer)) //nolint:errcheck - oa.ObjectName = &ntPath - oa.Attributes = windows.OBJ_CASE_INSENSITIVE - - // The security descriptor is only needed for the first pipe. - if first { - if sd != nil { - //todo: does `sdb` need to be allocated on the heap, or can go allocate it? - l := uint32(len(sd)) - sdb, err := windows.LocalAlloc(0, l) - if err != nil { - return 0, fmt.Errorf("LocalAlloc for security descriptor with of length %d: %w", l, err) - } - defer windows.LocalFree(windows.Handle(sdb)) //nolint:errcheck - copy((*[0xffff]byte)(unsafe.Pointer(sdb))[:], sd) - oa.SecurityDescriptor = (*securityDescriptor)(unsafe.Pointer(sdb)) - } else { - // Construct the default named pipe security descriptor. - var dacl uintptr - if err := rtlDefaultNpAcl(&dacl).Err(); err != nil { - return 0, fmt.Errorf("getting default named pipe ACL: %w", err) - } - defer windows.LocalFree(windows.Handle(dacl)) //nolint:errcheck - - sdb := &securityDescriptor{ - Revision: 1, - Control: windows.SE_DACL_PRESENT, - Dacl: dacl, - } - oa.SecurityDescriptor = sdb - } - } - - typ := uint32(windows.FILE_PIPE_REJECT_REMOTE_CLIENTS) - if c.MessageMode { - typ |= windows.FILE_PIPE_MESSAGE_TYPE - } - - disposition := fs.FILE_OPEN - access := fs.GENERIC_READ | fs.GENERIC_WRITE | fs.SYNCHRONIZE - if first { - disposition = fs.FILE_CREATE - // By not asking for read or write access, the named pipe file system - // will put this pipe into an initially disconnected state, blocking - // client connections until the next call with first == false. - access = fs.SYNCHRONIZE - } - - timeout := int64(-50 * 10000) // 50ms - - var ( - h windows.Handle - iosb ioStatusBlock - ) - err = ntCreateNamedPipeFile(&h, - access, - &oa, - &iosb, - fs.FILE_SHARE_READ|fs.FILE_SHARE_WRITE, - disposition, - 0, - typ, - 0, - 0, - 0xffffffff, - uint32(c.InputBufferSize), - uint32(c.OutputBufferSize), - &timeout).Err() - if err != nil { - return 0, &os.PathError{Op: "open", Path: path, Err: err} - } - - runtime.KeepAlive(ntPath) - return h, nil -} - -func (l *win32PipeListener) makeServerPipe() (*win32File, error) { - h, err := makeServerPipeHandle(l.path, nil, &l.config, false) - if err != nil { - return nil, err - } - f, err := makeWin32File(h) - if err != nil { - windows.Close(h) - return nil, err - } - return f, nil -} - -func (l *win32PipeListener) makeConnectedServerPipe() (*win32File, error) { - p, err := l.makeServerPipe() - if err != nil { - return nil, err - } - - // Wait for the client to connect. - ch := make(chan error) - go func(p *win32File) { - ch <- connectPipe(p) - }(p) - - select { - case err = <-ch: - if err != nil { - p.Close() - p = nil - } - case <-l.closeCh: - // Abort the connect request by closing the handle. - p.Close() - p = nil - err = <-ch - if err == nil || err == ErrFileClosed { //nolint:errorlint // err is Errno - err = ErrPipeListenerClosed - } - } - return p, err -} - -func (l *win32PipeListener) listenerRoutine() { - closed := false - for !closed { - select { - case <-l.closeCh: - closed = true - case responseCh := <-l.acceptCh: - var ( - p *win32File - err error - ) - for { - p, err = l.makeConnectedServerPipe() - // If the connection was immediately closed by the client, try - // again. - if err != windows.ERROR_NO_DATA { //nolint:errorlint // err is Errno - break - } - } - responseCh <- acceptResponse{p, err} - closed = err == ErrPipeListenerClosed //nolint:errorlint // err is Errno - } - } - windows.Close(l.firstHandle) - l.firstHandle = 0 - // Notify Close() and Accept() callers that the handle has been closed. - close(l.doneCh) -} - -// PipeConfig contain configuration for the pipe listener. -type PipeConfig struct { - // SecurityDescriptor contains a Windows security descriptor in SDDL format. - SecurityDescriptor string - - // MessageMode determines whether the pipe is in byte or message mode. In either - // case the pipe is read in byte mode by default. The only practical difference in - // this implementation is that CloseWrite() is only supported for message mode pipes; - // CloseWrite() is implemented as a zero-byte write, but zero-byte writes are only - // transferred to the reader (and returned as io.EOF in this implementation) - // when the pipe is in message mode. - MessageMode bool - - // InputBufferSize specifies the size of the input buffer, in bytes. - InputBufferSize int32 - - // OutputBufferSize specifies the size of the output buffer, in bytes. - OutputBufferSize int32 -} - -// ListenPipe creates a listener on a Windows named pipe path, e.g. \\.\pipe\mypipe. -// The pipe must not already exist. -func ListenPipe(path string, c *PipeConfig) (net.Listener, error) { - var ( - sd []byte - err error - ) - if c == nil { - c = &PipeConfig{} - } - if c.SecurityDescriptor != "" { - sd, err = SddlToSecurityDescriptor(c.SecurityDescriptor) - if err != nil { - return nil, err - } - } - h, err := makeServerPipeHandle(path, sd, c, true) - if err != nil { - return nil, err - } - l := &win32PipeListener{ - firstHandle: h, - path: path, - config: *c, - acceptCh: make(chan (chan acceptResponse)), - closeCh: make(chan int), - doneCh: make(chan int), - } - go l.listenerRoutine() - return l, nil -} - -func connectPipe(p *win32File) error { - c, err := p.prepareIO() - if err != nil { - return err - } - defer p.wg.Done() - - err = connectNamedPipe(p.handle, &c.o) - _, err = p.asyncIO(c, nil, 0, err) - if err != nil && err != windows.ERROR_PIPE_CONNECTED { //nolint:errorlint // err is Errno - return err - } - return nil -} - -func (l *win32PipeListener) Accept() (net.Conn, error) { - ch := make(chan acceptResponse) - select { - case l.acceptCh <- ch: - response := <-ch - err := response.err - if err != nil { - return nil, err - } - if l.config.MessageMode { - return &win32MessageBytePipe{ - win32Pipe: win32Pipe{win32File: response.f, path: l.path}, - }, nil - } - return &win32Pipe{win32File: response.f, path: l.path}, nil - case <-l.doneCh: - return nil, ErrPipeListenerClosed - } -} - -func (l *win32PipeListener) Close() error { - select { - case l.closeCh <- 1: - <-l.doneCh - case <-l.doneCh: - } - return nil -} - -func (l *win32PipeListener) Addr() net.Addr { - return pipeAddress(l.path) -} diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go deleted file mode 100644 index 48ce4e924..000000000 --- a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid.go +++ /dev/null @@ -1,232 +0,0 @@ -// Package guid provides a GUID type. The backing structure for a GUID is -// identical to that used by the golang.org/x/sys/windows GUID type. -// There are two main binary encodings used for a GUID, the big-endian encoding, -// and the Windows (mixed-endian) encoding. See here for details: -// https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding -package guid - -import ( - "crypto/rand" - "crypto/sha1" //nolint:gosec // not used for secure application - "encoding" - "encoding/binary" - "fmt" - "strconv" -) - -//go:generate go run golang.org/x/tools/cmd/stringer -type=Variant -trimprefix=Variant -linecomment - -// Variant specifies which GUID variant (or "type") of the GUID. It determines -// how the entirety of the rest of the GUID is interpreted. -type Variant uint8 - -// The variants specified by RFC 4122 section 4.1.1. -const ( - // VariantUnknown specifies a GUID variant which does not conform to one of - // the variant encodings specified in RFC 4122. - VariantUnknown Variant = iota - VariantNCS - VariantRFC4122 // RFC 4122 - VariantMicrosoft - VariantFuture -) - -// Version specifies how the bits in the GUID were generated. For instance, a -// version 4 GUID is randomly generated, and a version 5 is generated from the -// hash of an input string. -type Version uint8 - -func (v Version) String() string { - return strconv.FormatUint(uint64(v), 10) -} - -var _ = (encoding.TextMarshaler)(GUID{}) -var _ = (encoding.TextUnmarshaler)(&GUID{}) - -// NewV4 returns a new version 4 (pseudorandom) GUID, as defined by RFC 4122. -func NewV4() (GUID, error) { - var b [16]byte - if _, err := rand.Read(b[:]); err != nil { - return GUID{}, err - } - - g := FromArray(b) - g.setVersion(4) // Version 4 means randomly generated. - g.setVariant(VariantRFC4122) - - return g, nil -} - -// NewV5 returns a new version 5 (generated from a string via SHA-1 hashing) -// GUID, as defined by RFC 4122. The RFC is unclear on the encoding of the name, -// and the sample code treats it as a series of bytes, so we do the same here. -// -// Some implementations, such as those found on Windows, treat the name as a -// big-endian UTF16 stream of bytes. If that is desired, the string can be -// encoded as such before being passed to this function. -func NewV5(namespace GUID, name []byte) (GUID, error) { - b := sha1.New() //nolint:gosec // not used for secure application - namespaceBytes := namespace.ToArray() - b.Write(namespaceBytes[:]) - b.Write(name) - - a := [16]byte{} - copy(a[:], b.Sum(nil)) - - g := FromArray(a) - g.setVersion(5) // Version 5 means generated from a string. - g.setVariant(VariantRFC4122) - - return g, nil -} - -func fromArray(b [16]byte, order binary.ByteOrder) GUID { - var g GUID - g.Data1 = order.Uint32(b[0:4]) - g.Data2 = order.Uint16(b[4:6]) - g.Data3 = order.Uint16(b[6:8]) - copy(g.Data4[:], b[8:16]) - return g -} - -func (g GUID) toArray(order binary.ByteOrder) [16]byte { - b := [16]byte{} - order.PutUint32(b[0:4], g.Data1) - order.PutUint16(b[4:6], g.Data2) - order.PutUint16(b[6:8], g.Data3) - copy(b[8:16], g.Data4[:]) - return b -} - -// FromArray constructs a GUID from a big-endian encoding array of 16 bytes. -func FromArray(b [16]byte) GUID { - return fromArray(b, binary.BigEndian) -} - -// ToArray returns an array of 16 bytes representing the GUID in big-endian -// encoding. -func (g GUID) ToArray() [16]byte { - return g.toArray(binary.BigEndian) -} - -// FromWindowsArray constructs a GUID from a Windows encoding array of bytes. -func FromWindowsArray(b [16]byte) GUID { - return fromArray(b, binary.LittleEndian) -} - -// ToWindowsArray returns an array of 16 bytes representing the GUID in Windows -// encoding. -func (g GUID) ToWindowsArray() [16]byte { - return g.toArray(binary.LittleEndian) -} - -func (g GUID) String() string { - return fmt.Sprintf( - "%08x-%04x-%04x-%04x-%012x", - g.Data1, - g.Data2, - g.Data3, - g.Data4[:2], - g.Data4[2:]) -} - -// FromString parses a string containing a GUID and returns the GUID. The only -// format currently supported is the `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` -// format. -func FromString(s string) (GUID, error) { - if len(s) != 36 { - return GUID{}, fmt.Errorf("invalid GUID %q", s) - } - if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { - return GUID{}, fmt.Errorf("invalid GUID %q", s) - } - - var g GUID - - data1, err := strconv.ParseUint(s[0:8], 16, 32) - if err != nil { - return GUID{}, fmt.Errorf("invalid GUID %q", s) - } - g.Data1 = uint32(data1) - - data2, err := strconv.ParseUint(s[9:13], 16, 16) - if err != nil { - return GUID{}, fmt.Errorf("invalid GUID %q", s) - } - g.Data2 = uint16(data2) - - data3, err := strconv.ParseUint(s[14:18], 16, 16) - if err != nil { - return GUID{}, fmt.Errorf("invalid GUID %q", s) - } - g.Data3 = uint16(data3) - - for i, x := range []int{19, 21, 24, 26, 28, 30, 32, 34} { - v, err := strconv.ParseUint(s[x:x+2], 16, 8) - if err != nil { - return GUID{}, fmt.Errorf("invalid GUID %q", s) - } - g.Data4[i] = uint8(v) - } - - return g, nil -} - -func (g *GUID) setVariant(v Variant) { - d := g.Data4[0] - switch v { - case VariantNCS: - d = (d & 0x7f) - case VariantRFC4122: - d = (d & 0x3f) | 0x80 - case VariantMicrosoft: - d = (d & 0x1f) | 0xc0 - case VariantFuture: - d = (d & 0x0f) | 0xe0 - case VariantUnknown: - fallthrough - default: - panic(fmt.Sprintf("invalid variant: %d", v)) - } - g.Data4[0] = d -} - -// Variant returns the GUID variant, as defined in RFC 4122. -func (g GUID) Variant() Variant { - b := g.Data4[0] - if b&0x80 == 0 { - return VariantNCS - } else if b&0xc0 == 0x80 { - return VariantRFC4122 - } else if b&0xe0 == 0xc0 { - return VariantMicrosoft - } else if b&0xe0 == 0xe0 { - return VariantFuture - } - return VariantUnknown -} - -func (g *GUID) setVersion(v Version) { - g.Data3 = (g.Data3 & 0x0fff) | (uint16(v) << 12) -} - -// Version returns the GUID version, as defined in RFC 4122. -func (g GUID) Version() Version { - return Version((g.Data3 & 0xF000) >> 12) -} - -// MarshalText returns the textual representation of the GUID. -func (g GUID) MarshalText() ([]byte, error) { - return []byte(g.String()), nil -} - -// UnmarshalText takes the textual representation of a GUID, and unmarhals it -// into this GUID. -func (g *GUID) UnmarshalText(text []byte) error { - g2, err := FromString(string(text)) - if err != nil { - return err - } - *g = g2 - return nil -} diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go deleted file mode 100644 index 805bd3548..000000000 --- a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_nonwindows.go +++ /dev/null @@ -1,16 +0,0 @@ -//go:build !windows -// +build !windows - -package guid - -// GUID represents a GUID/UUID. It has the same structure as -// golang.org/x/sys/windows.GUID so that it can be used with functions expecting -// that type. It is defined as its own type as that is only available to builds -// targeted at `windows`. The representation matches that used by native Windows -// code. -type GUID struct { - Data1 uint32 - Data2 uint16 - Data3 uint16 - Data4 [8]byte -} diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go deleted file mode 100644 index 27e45ee5c..000000000 --- a/vendor/github.com/Microsoft/go-winio/pkg/guid/guid_windows.go +++ /dev/null @@ -1,13 +0,0 @@ -//go:build windows -// +build windows - -package guid - -import "golang.org/x/sys/windows" - -// GUID represents a GUID/UUID. It has the same structure as -// golang.org/x/sys/windows.GUID so that it can be used with functions expecting -// that type. It is defined as its own type so that stringification and -// marshaling can be supported. The representation matches that used by native -// Windows code. -type GUID windows.GUID diff --git a/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go b/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go deleted file mode 100644 index 4076d3132..000000000 --- a/vendor/github.com/Microsoft/go-winio/pkg/guid/variant_string.go +++ /dev/null @@ -1,27 +0,0 @@ -// Code generated by "stringer -type=Variant -trimprefix=Variant -linecomment"; DO NOT EDIT. - -package guid - -import "strconv" - -func _() { - // An "invalid array index" compiler error signifies that the constant values have changed. - // Re-run the stringer command to generate them again. - var x [1]struct{} - _ = x[VariantUnknown-0] - _ = x[VariantNCS-1] - _ = x[VariantRFC4122-2] - _ = x[VariantMicrosoft-3] - _ = x[VariantFuture-4] -} - -const _Variant_name = "UnknownNCSRFC 4122MicrosoftFuture" - -var _Variant_index = [...]uint8{0, 7, 10, 18, 27, 33} - -func (i Variant) String() string { - if i >= Variant(len(_Variant_index)-1) { - return "Variant(" + strconv.FormatInt(int64(i), 10) + ")" - } - return _Variant_name[_Variant_index[i]:_Variant_index[i+1]] -} diff --git a/vendor/github.com/Microsoft/go-winio/privilege.go b/vendor/github.com/Microsoft/go-winio/privilege.go deleted file mode 100644 index d9b90b6e8..000000000 --- a/vendor/github.com/Microsoft/go-winio/privilege.go +++ /dev/null @@ -1,196 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "bytes" - "encoding/binary" - "fmt" - "runtime" - "sync" - "unicode/utf16" - - "golang.org/x/sys/windows" -) - -//sys adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges -//sys impersonateSelf(level uint32) (err error) = advapi32.ImpersonateSelf -//sys revertToSelf() (err error) = advapi32.RevertToSelf -//sys openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) = advapi32.OpenThreadToken -//sys getCurrentThread() (h windows.Handle) = GetCurrentThread -//sys lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) = advapi32.LookupPrivilegeValueW -//sys lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW -//sys lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) = advapi32.LookupPrivilegeDisplayNameW - -const ( - //revive:disable-next-line:var-naming ALL_CAPS - SE_PRIVILEGE_ENABLED = windows.SE_PRIVILEGE_ENABLED - - //revive:disable-next-line:var-naming ALL_CAPS - ERROR_NOT_ALL_ASSIGNED windows.Errno = windows.ERROR_NOT_ALL_ASSIGNED - - SeBackupPrivilege = "SeBackupPrivilege" - SeRestorePrivilege = "SeRestorePrivilege" - SeSecurityPrivilege = "SeSecurityPrivilege" -) - -var ( - privNames = make(map[string]uint64) - privNameMutex sync.Mutex -) - -// PrivilegeError represents an error enabling privileges. -type PrivilegeError struct { - privileges []uint64 -} - -func (e *PrivilegeError) Error() string { - s := "Could not enable privilege " - if len(e.privileges) > 1 { - s = "Could not enable privileges " - } - for i, p := range e.privileges { - if i != 0 { - s += ", " - } - s += `"` - s += getPrivilegeName(p) - s += `"` - } - return s -} - -// RunWithPrivilege enables a single privilege for a function call. -func RunWithPrivilege(name string, fn func() error) error { - return RunWithPrivileges([]string{name}, fn) -} - -// RunWithPrivileges enables privileges for a function call. -func RunWithPrivileges(names []string, fn func() error) error { - privileges, err := mapPrivileges(names) - if err != nil { - return err - } - runtime.LockOSThread() - defer runtime.UnlockOSThread() - token, err := newThreadToken() - if err != nil { - return err - } - defer releaseThreadToken(token) - err = adjustPrivileges(token, privileges, SE_PRIVILEGE_ENABLED) - if err != nil { - return err - } - return fn() -} - -func mapPrivileges(names []string) ([]uint64, error) { - privileges := make([]uint64, 0, len(names)) - privNameMutex.Lock() - defer privNameMutex.Unlock() - for _, name := range names { - p, ok := privNames[name] - if !ok { - err := lookupPrivilegeValue("", name, &p) - if err != nil { - return nil, err - } - privNames[name] = p - } - privileges = append(privileges, p) - } - return privileges, nil -} - -// EnableProcessPrivileges enables privileges globally for the process. -func EnableProcessPrivileges(names []string) error { - return enableDisableProcessPrivilege(names, SE_PRIVILEGE_ENABLED) -} - -// DisableProcessPrivileges disables privileges globally for the process. -func DisableProcessPrivileges(names []string) error { - return enableDisableProcessPrivilege(names, 0) -} - -func enableDisableProcessPrivilege(names []string, action uint32) error { - privileges, err := mapPrivileges(names) - if err != nil { - return err - } - - p := windows.CurrentProcess() - var token windows.Token - err = windows.OpenProcessToken(p, windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, &token) - if err != nil { - return err - } - - defer token.Close() - return adjustPrivileges(token, privileges, action) -} - -func adjustPrivileges(token windows.Token, privileges []uint64, action uint32) error { - var b bytes.Buffer - _ = binary.Write(&b, binary.LittleEndian, uint32(len(privileges))) - for _, p := range privileges { - _ = binary.Write(&b, binary.LittleEndian, p) - _ = binary.Write(&b, binary.LittleEndian, action) - } - prevState := make([]byte, b.Len()) - reqSize := uint32(0) - success, err := adjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(len(prevState)), &prevState[0], &reqSize) - if !success { - return err - } - if err == ERROR_NOT_ALL_ASSIGNED { //nolint:errorlint // err is Errno - return &PrivilegeError{privileges} - } - return nil -} - -func getPrivilegeName(luid uint64) string { - var nameBuffer [256]uint16 - bufSize := uint32(len(nameBuffer)) - err := lookupPrivilegeName("", &luid, &nameBuffer[0], &bufSize) - if err != nil { - return fmt.Sprintf("", luid) - } - - var displayNameBuffer [256]uint16 - displayBufSize := uint32(len(displayNameBuffer)) - var langID uint32 - err = lookupPrivilegeDisplayName("", &nameBuffer[0], &displayNameBuffer[0], &displayBufSize, &langID) - if err != nil { - return fmt.Sprintf("", string(utf16.Decode(nameBuffer[:bufSize]))) - } - - return string(utf16.Decode(displayNameBuffer[:displayBufSize])) -} - -func newThreadToken() (windows.Token, error) { - err := impersonateSelf(windows.SecurityImpersonation) - if err != nil { - return 0, err - } - - var token windows.Token - err = openThreadToken(getCurrentThread(), windows.TOKEN_ADJUST_PRIVILEGES|windows.TOKEN_QUERY, false, &token) - if err != nil { - rerr := revertToSelf() - if rerr != nil { - panic(rerr) - } - return 0, err - } - return token, nil -} - -func releaseThreadToken(h windows.Token) { - err := revertToSelf() - if err != nil { - panic(err) - } - h.Close() -} diff --git a/vendor/github.com/Microsoft/go-winio/reparse.go b/vendor/github.com/Microsoft/go-winio/reparse.go deleted file mode 100644 index 67d1a104a..000000000 --- a/vendor/github.com/Microsoft/go-winio/reparse.go +++ /dev/null @@ -1,131 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "bytes" - "encoding/binary" - "fmt" - "strings" - "unicode/utf16" - "unsafe" -) - -const ( - reparseTagMountPoint = 0xA0000003 - reparseTagSymlink = 0xA000000C -) - -type reparseDataBuffer struct { - ReparseTag uint32 - ReparseDataLength uint16 - Reserved uint16 - SubstituteNameOffset uint16 - SubstituteNameLength uint16 - PrintNameOffset uint16 - PrintNameLength uint16 -} - -// ReparsePoint describes a Win32 symlink or mount point. -type ReparsePoint struct { - Target string - IsMountPoint bool -} - -// UnsupportedReparsePointError is returned when trying to decode a non-symlink or -// mount point reparse point. -type UnsupportedReparsePointError struct { - Tag uint32 -} - -func (e *UnsupportedReparsePointError) Error() string { - return fmt.Sprintf("unsupported reparse point %x", e.Tag) -} - -// DecodeReparsePoint decodes a Win32 REPARSE_DATA_BUFFER structure containing either a symlink -// or a mount point. -func DecodeReparsePoint(b []byte) (*ReparsePoint, error) { - tag := binary.LittleEndian.Uint32(b[0:4]) - return DecodeReparsePointData(tag, b[8:]) -} - -func DecodeReparsePointData(tag uint32, b []byte) (*ReparsePoint, error) { - isMountPoint := false - switch tag { - case reparseTagMountPoint: - isMountPoint = true - case reparseTagSymlink: - default: - return nil, &UnsupportedReparsePointError{tag} - } - nameOffset := 8 + binary.LittleEndian.Uint16(b[4:6]) - if !isMountPoint { - nameOffset += 4 - } - nameLength := binary.LittleEndian.Uint16(b[6:8]) - name := make([]uint16, nameLength/2) - err := binary.Read(bytes.NewReader(b[nameOffset:nameOffset+nameLength]), binary.LittleEndian, &name) - if err != nil { - return nil, err - } - return &ReparsePoint{string(utf16.Decode(name)), isMountPoint}, nil -} - -func isDriveLetter(c byte) bool { - return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') -} - -// EncodeReparsePoint encodes a Win32 REPARSE_DATA_BUFFER structure describing a symlink or -// mount point. -func EncodeReparsePoint(rp *ReparsePoint) []byte { - // Generate an NT path and determine if this is a relative path. - var ntTarget string - relative := false - if strings.HasPrefix(rp.Target, `\\?\`) { - ntTarget = `\??\` + rp.Target[4:] - } else if strings.HasPrefix(rp.Target, `\\`) { - ntTarget = `\??\UNC\` + rp.Target[2:] - } else if len(rp.Target) >= 2 && isDriveLetter(rp.Target[0]) && rp.Target[1] == ':' { - ntTarget = `\??\` + rp.Target - } else { - ntTarget = rp.Target - relative = true - } - - // The paths must be NUL-terminated even though they are counted strings. - target16 := utf16.Encode([]rune(rp.Target + "\x00")) - ntTarget16 := utf16.Encode([]rune(ntTarget + "\x00")) - - size := int(unsafe.Sizeof(reparseDataBuffer{})) - 8 - size += len(ntTarget16)*2 + len(target16)*2 - - tag := uint32(reparseTagMountPoint) - if !rp.IsMountPoint { - tag = reparseTagSymlink - size += 4 // Add room for symlink flags - } - - data := reparseDataBuffer{ - ReparseTag: tag, - ReparseDataLength: uint16(size), - SubstituteNameOffset: 0, - SubstituteNameLength: uint16((len(ntTarget16) - 1) * 2), - PrintNameOffset: uint16(len(ntTarget16) * 2), - PrintNameLength: uint16((len(target16) - 1) * 2), - } - - var b bytes.Buffer - _ = binary.Write(&b, binary.LittleEndian, &data) - if !rp.IsMountPoint { - flags := uint32(0) - if relative { - flags |= 1 - } - _ = binary.Write(&b, binary.LittleEndian, flags) - } - - _ = binary.Write(&b, binary.LittleEndian, ntTarget16) - _ = binary.Write(&b, binary.LittleEndian, target16) - return b.Bytes() -} diff --git a/vendor/github.com/Microsoft/go-winio/sd.go b/vendor/github.com/Microsoft/go-winio/sd.go deleted file mode 100644 index c3685e98e..000000000 --- a/vendor/github.com/Microsoft/go-winio/sd.go +++ /dev/null @@ -1,133 +0,0 @@ -//go:build windows -// +build windows - -package winio - -import ( - "errors" - "fmt" - "unsafe" - - "golang.org/x/sys/windows" -) - -//sys lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountNameW -//sys lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) = advapi32.LookupAccountSidW -//sys convertSidToStringSid(sid *byte, str **uint16) (err error) = advapi32.ConvertSidToStringSidW -//sys convertStringSidToSid(str *uint16, sid **byte) (err error) = advapi32.ConvertStringSidToSidW - -type AccountLookupError struct { - Name string - Err error -} - -func (e *AccountLookupError) Error() string { - if e.Name == "" { - return "lookup account: empty account name specified" - } - var s string - switch { - case errors.Is(e.Err, windows.ERROR_INVALID_SID): - s = "the security ID structure is invalid" - case errors.Is(e.Err, windows.ERROR_NONE_MAPPED): - s = "not found" - default: - s = e.Err.Error() - } - return "lookup account " + e.Name + ": " + s -} - -func (e *AccountLookupError) Unwrap() error { return e.Err } - -type SddlConversionError struct { - Sddl string - Err error -} - -func (e *SddlConversionError) Error() string { - return "convert " + e.Sddl + ": " + e.Err.Error() -} - -func (e *SddlConversionError) Unwrap() error { return e.Err } - -// LookupSidByName looks up the SID of an account by name -// -//revive:disable-next-line:var-naming SID, not Sid -func LookupSidByName(name string) (sid string, err error) { - if name == "" { - return "", &AccountLookupError{name, windows.ERROR_NONE_MAPPED} - } - - var sidSize, sidNameUse, refDomainSize uint32 - err = lookupAccountName(nil, name, nil, &sidSize, nil, &refDomainSize, &sidNameUse) - if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno - return "", &AccountLookupError{name, err} - } - sidBuffer := make([]byte, sidSize) - refDomainBuffer := make([]uint16, refDomainSize) - err = lookupAccountName(nil, name, &sidBuffer[0], &sidSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse) - if err != nil { - return "", &AccountLookupError{name, err} - } - var strBuffer *uint16 - err = convertSidToStringSid(&sidBuffer[0], &strBuffer) - if err != nil { - return "", &AccountLookupError{name, err} - } - sid = windows.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(strBuffer))[:]) - _, _ = windows.LocalFree(windows.Handle(unsafe.Pointer(strBuffer))) - return sid, nil -} - -// LookupNameBySid looks up the name of an account by SID -// -//revive:disable-next-line:var-naming SID, not Sid -func LookupNameBySid(sid string) (name string, err error) { - if sid == "" { - return "", &AccountLookupError{sid, windows.ERROR_NONE_MAPPED} - } - - sidBuffer, err := windows.UTF16PtrFromString(sid) - if err != nil { - return "", &AccountLookupError{sid, err} - } - - var sidPtr *byte - if err = convertStringSidToSid(sidBuffer, &sidPtr); err != nil { - return "", &AccountLookupError{sid, err} - } - defer windows.LocalFree(windows.Handle(unsafe.Pointer(sidPtr))) //nolint:errcheck - - var nameSize, refDomainSize, sidNameUse uint32 - err = lookupAccountSid(nil, sidPtr, nil, &nameSize, nil, &refDomainSize, &sidNameUse) - if err != nil && err != windows.ERROR_INSUFFICIENT_BUFFER { //nolint:errorlint // err is Errno - return "", &AccountLookupError{sid, err} - } - - nameBuffer := make([]uint16, nameSize) - refDomainBuffer := make([]uint16, refDomainSize) - err = lookupAccountSid(nil, sidPtr, &nameBuffer[0], &nameSize, &refDomainBuffer[0], &refDomainSize, &sidNameUse) - if err != nil { - return "", &AccountLookupError{sid, err} - } - - name = windows.UTF16ToString(nameBuffer) - return name, nil -} - -func SddlToSecurityDescriptor(sddl string) ([]byte, error) { - sd, err := windows.SecurityDescriptorFromString(sddl) - if err != nil { - return nil, &SddlConversionError{Sddl: sddl, Err: err} - } - b := unsafe.Slice((*byte)(unsafe.Pointer(sd)), sd.Length()) - return b, nil -} - -func SecurityDescriptorToSddl(sd []byte) (string, error) { - if l := int(unsafe.Sizeof(windows.SECURITY_DESCRIPTOR{})); len(sd) < l { - return "", fmt.Errorf("SecurityDescriptor (%d) smaller than expected (%d): %w", len(sd), l, windows.ERROR_INCORRECT_SIZE) - } - s := (*windows.SECURITY_DESCRIPTOR)(unsafe.Pointer(&sd[0])) - return s.String(), nil -} diff --git a/vendor/github.com/Microsoft/go-winio/syscall.go b/vendor/github.com/Microsoft/go-winio/syscall.go deleted file mode 100644 index a6ca111b3..000000000 --- a/vendor/github.com/Microsoft/go-winio/syscall.go +++ /dev/null @@ -1,5 +0,0 @@ -//go:build windows - -package winio - -//go:generate go run github.com/Microsoft/go-winio/tools/mkwinsyscall -output zsyscall_windows.go ./*.go diff --git a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go b/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go deleted file mode 100644 index 89b66eda8..000000000 --- a/vendor/github.com/Microsoft/go-winio/zsyscall_windows.go +++ /dev/null @@ -1,378 +0,0 @@ -//go:build windows - -// Code generated by 'go generate' using "github.com/Microsoft/go-winio/tools/mkwinsyscall"; DO NOT EDIT. - -package winio - -import ( - "syscall" - "unsafe" - - "golang.org/x/sys/windows" -) - -var _ unsafe.Pointer - -// Do the interface allocations only once for common -// Errno values. -const ( - errnoERROR_IO_PENDING = 997 -) - -var ( - errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) - errERROR_EINVAL error = syscall.EINVAL -) - -// errnoErr returns common boxed Errno values, to prevent -// allocations at runtime. -func errnoErr(e syscall.Errno) error { - switch e { - case 0: - return errERROR_EINVAL - case errnoERROR_IO_PENDING: - return errERROR_IO_PENDING - } - return e -} - -var ( - modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - modntdll = windows.NewLazySystemDLL("ntdll.dll") - modws2_32 = windows.NewLazySystemDLL("ws2_32.dll") - - procAdjustTokenPrivileges = modadvapi32.NewProc("AdjustTokenPrivileges") - procConvertSidToStringSidW = modadvapi32.NewProc("ConvertSidToStringSidW") - procConvertStringSidToSidW = modadvapi32.NewProc("ConvertStringSidToSidW") - procImpersonateSelf = modadvapi32.NewProc("ImpersonateSelf") - procLookupAccountNameW = modadvapi32.NewProc("LookupAccountNameW") - procLookupAccountSidW = modadvapi32.NewProc("LookupAccountSidW") - procLookupPrivilegeDisplayNameW = modadvapi32.NewProc("LookupPrivilegeDisplayNameW") - procLookupPrivilegeNameW = modadvapi32.NewProc("LookupPrivilegeNameW") - procLookupPrivilegeValueW = modadvapi32.NewProc("LookupPrivilegeValueW") - procOpenThreadToken = modadvapi32.NewProc("OpenThreadToken") - procRevertToSelf = modadvapi32.NewProc("RevertToSelf") - procBackupRead = modkernel32.NewProc("BackupRead") - procBackupWrite = modkernel32.NewProc("BackupWrite") - procCancelIoEx = modkernel32.NewProc("CancelIoEx") - procConnectNamedPipe = modkernel32.NewProc("ConnectNamedPipe") - procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") - procCreateNamedPipeW = modkernel32.NewProc("CreateNamedPipeW") - procDisconnectNamedPipe = modkernel32.NewProc("DisconnectNamedPipe") - procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") - procGetNamedPipeHandleStateW = modkernel32.NewProc("GetNamedPipeHandleStateW") - procGetNamedPipeInfo = modkernel32.NewProc("GetNamedPipeInfo") - procGetQueuedCompletionStatus = modkernel32.NewProc("GetQueuedCompletionStatus") - procSetFileCompletionNotificationModes = modkernel32.NewProc("SetFileCompletionNotificationModes") - procNtCreateNamedPipeFile = modntdll.NewProc("NtCreateNamedPipeFile") - procRtlDefaultNpAcl = modntdll.NewProc("RtlDefaultNpAcl") - procRtlDosPathNameToNtPathName_U = modntdll.NewProc("RtlDosPathNameToNtPathName_U") - procRtlNtStatusToDosErrorNoTeb = modntdll.NewProc("RtlNtStatusToDosErrorNoTeb") - procWSAGetOverlappedResult = modws2_32.NewProc("WSAGetOverlappedResult") -) - -func adjustTokenPrivileges(token windows.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { - var _p0 uint32 - if releaseAll { - _p0 = 1 - } - r0, _, e1 := syscall.SyscallN(procAdjustTokenPrivileges.Addr(), uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) - success = r0 != 0 - if true { - err = errnoErr(e1) - } - return -} - -func convertSidToStringSid(sid *byte, str **uint16) (err error) { - r1, _, e1 := syscall.SyscallN(procConvertSidToStringSidW.Addr(), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(str))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func convertStringSidToSid(str *uint16, sid **byte) (err error) { - r1, _, e1 := syscall.SyscallN(procConvertStringSidToSidW.Addr(), uintptr(unsafe.Pointer(str)), uintptr(unsafe.Pointer(sid))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func impersonateSelf(level uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procImpersonateSelf.Addr(), uintptr(level)) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func lookupAccountName(systemName *uint16, accountName string, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(accountName) - if err != nil { - return - } - return _lookupAccountName(systemName, _p0, sid, sidSize, refDomain, refDomainSize, sidNameUse) -} - -func _lookupAccountName(systemName *uint16, accountName *uint16, sid *byte, sidSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procLookupAccountNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(accountName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(sidSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func lookupAccountSid(systemName *uint16, sid *byte, name *uint16, nameSize *uint32, refDomain *uint16, refDomainSize *uint32, sidNameUse *uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procLookupAccountSidW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(sid)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(nameSize)), uintptr(unsafe.Pointer(refDomain)), uintptr(unsafe.Pointer(refDomainSize)), uintptr(unsafe.Pointer(sidNameUse))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func lookupPrivilegeDisplayName(systemName string, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - return _lookupPrivilegeDisplayName(_p0, name, buffer, size, languageId) -} - -func _lookupPrivilegeDisplayName(systemName *uint16, name *uint16, buffer *uint16, size *uint32, languageId *uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procLookupPrivilegeDisplayNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), uintptr(unsafe.Pointer(languageId))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func lookupPrivilegeName(systemName string, luid *uint64, buffer *uint16, size *uint32) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - return _lookupPrivilegeName(_p0, luid, buffer, size) -} - -func _lookupPrivilegeName(systemName *uint16, luid *uint64, buffer *uint16, size *uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procLookupPrivilegeNameW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func lookupPrivilegeValue(systemName string, name string, luid *uint64) (err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(systemName) - if err != nil { - return - } - var _p1 *uint16 - _p1, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _lookupPrivilegeValue(_p0, _p1, luid) -} - -func _lookupPrivilegeValue(systemName *uint16, name *uint16, luid *uint64) (err error) { - r1, _, e1 := syscall.SyscallN(procLookupPrivilegeValueW.Addr(), uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func openThreadToken(thread windows.Handle, accessMask uint32, openAsSelf bool, token *windows.Token) (err error) { - var _p0 uint32 - if openAsSelf { - _p0 = 1 - } - r1, _, e1 := syscall.SyscallN(procOpenThreadToken.Addr(), uintptr(thread), uintptr(accessMask), uintptr(_p0), uintptr(unsafe.Pointer(token))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func revertToSelf() (err error) { - r1, _, e1 := syscall.SyscallN(procRevertToSelf.Addr()) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func backupRead(h windows.Handle, b []byte, bytesRead *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { - var _p0 *byte - if len(b) > 0 { - _p0 = &b[0] - } - var _p1 uint32 - if abort { - _p1 = 1 - } - var _p2 uint32 - if processSecurity { - _p2 = 1 - } - r1, _, e1 := syscall.SyscallN(procBackupRead.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesRead)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func backupWrite(h windows.Handle, b []byte, bytesWritten *uint32, abort bool, processSecurity bool, context *uintptr) (err error) { - var _p0 *byte - if len(b) > 0 { - _p0 = &b[0] - } - var _p1 uint32 - if abort { - _p1 = 1 - } - var _p2 uint32 - if processSecurity { - _p2 = 1 - } - r1, _, e1 := syscall.SyscallN(procBackupWrite.Addr(), uintptr(h), uintptr(unsafe.Pointer(_p0)), uintptr(len(b)), uintptr(unsafe.Pointer(bytesWritten)), uintptr(_p1), uintptr(_p2), uintptr(unsafe.Pointer(context))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func cancelIoEx(file windows.Handle, o *windows.Overlapped) (err error) { - r1, _, e1 := syscall.SyscallN(procCancelIoEx.Addr(), uintptr(file), uintptr(unsafe.Pointer(o))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func connectNamedPipe(pipe windows.Handle, o *windows.Overlapped) (err error) { - r1, _, e1 := syscall.SyscallN(procConnectNamedPipe.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(o))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func createIoCompletionPort(file windows.Handle, port windows.Handle, key uintptr, threadCount uint32) (newport windows.Handle, err error) { - r0, _, e1 := syscall.SyscallN(procCreateIoCompletionPort.Addr(), uintptr(file), uintptr(port), uintptr(key), uintptr(threadCount)) - newport = windows.Handle(r0) - if newport == 0 { - err = errnoErr(e1) - } - return -} - -func createNamedPipe(name string, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) { - var _p0 *uint16 - _p0, err = syscall.UTF16PtrFromString(name) - if err != nil { - return - } - return _createNamedPipe(_p0, flags, pipeMode, maxInstances, outSize, inSize, defaultTimeout, sa) -} - -func _createNamedPipe(name *uint16, flags uint32, pipeMode uint32, maxInstances uint32, outSize uint32, inSize uint32, defaultTimeout uint32, sa *windows.SecurityAttributes) (handle windows.Handle, err error) { - r0, _, e1 := syscall.SyscallN(procCreateNamedPipeW.Addr(), uintptr(unsafe.Pointer(name)), uintptr(flags), uintptr(pipeMode), uintptr(maxInstances), uintptr(outSize), uintptr(inSize), uintptr(defaultTimeout), uintptr(unsafe.Pointer(sa))) - handle = windows.Handle(r0) - if handle == windows.InvalidHandle { - err = errnoErr(e1) - } - return -} - -func disconnectNamedPipe(pipe windows.Handle) (err error) { - r1, _, e1 := syscall.SyscallN(procDisconnectNamedPipe.Addr(), uintptr(pipe)) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func getCurrentThread() (h windows.Handle) { - r0, _, _ := syscall.SyscallN(procGetCurrentThread.Addr()) - h = windows.Handle(r0) - return -} - -func getNamedPipeHandleState(pipe windows.Handle, state *uint32, curInstances *uint32, maxCollectionCount *uint32, collectDataTimeout *uint32, userName *uint16, maxUserNameSize uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procGetNamedPipeHandleStateW.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(state)), uintptr(unsafe.Pointer(curInstances)), uintptr(unsafe.Pointer(maxCollectionCount)), uintptr(unsafe.Pointer(collectDataTimeout)), uintptr(unsafe.Pointer(userName)), uintptr(maxUserNameSize)) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func getNamedPipeInfo(pipe windows.Handle, flags *uint32, outSize *uint32, inSize *uint32, maxInstances *uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procGetNamedPipeInfo.Addr(), uintptr(pipe), uintptr(unsafe.Pointer(flags)), uintptr(unsafe.Pointer(outSize)), uintptr(unsafe.Pointer(inSize)), uintptr(unsafe.Pointer(maxInstances))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func getQueuedCompletionStatus(port windows.Handle, bytes *uint32, key *uintptr, o **ioOperation, timeout uint32) (err error) { - r1, _, e1 := syscall.SyscallN(procGetQueuedCompletionStatus.Addr(), uintptr(port), uintptr(unsafe.Pointer(bytes)), uintptr(unsafe.Pointer(key)), uintptr(unsafe.Pointer(o)), uintptr(timeout)) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func setFileCompletionNotificationModes(h windows.Handle, flags uint8) (err error) { - r1, _, e1 := syscall.SyscallN(procSetFileCompletionNotificationModes.Addr(), uintptr(h), uintptr(flags)) - if r1 == 0 { - err = errnoErr(e1) - } - return -} - -func ntCreateNamedPipeFile(pipe *windows.Handle, access ntAccessMask, oa *objectAttributes, iosb *ioStatusBlock, share ntFileShareMode, disposition ntFileCreationDisposition, options ntFileOptions, typ uint32, readMode uint32, completionMode uint32, maxInstances uint32, inboundQuota uint32, outputQuota uint32, timeout *int64) (status ntStatus) { - r0, _, _ := syscall.SyscallN(procNtCreateNamedPipeFile.Addr(), uintptr(unsafe.Pointer(pipe)), uintptr(access), uintptr(unsafe.Pointer(oa)), uintptr(unsafe.Pointer(iosb)), uintptr(share), uintptr(disposition), uintptr(options), uintptr(typ), uintptr(readMode), uintptr(completionMode), uintptr(maxInstances), uintptr(inboundQuota), uintptr(outputQuota), uintptr(unsafe.Pointer(timeout))) - status = ntStatus(r0) - return -} - -func rtlDefaultNpAcl(dacl *uintptr) (status ntStatus) { - r0, _, _ := syscall.SyscallN(procRtlDefaultNpAcl.Addr(), uintptr(unsafe.Pointer(dacl))) - status = ntStatus(r0) - return -} - -func rtlDosPathNameToNtPathName(name *uint16, ntName *unicodeString, filePart uintptr, reserved uintptr) (status ntStatus) { - r0, _, _ := syscall.SyscallN(procRtlDosPathNameToNtPathName_U.Addr(), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(ntName)), uintptr(filePart), uintptr(reserved)) - status = ntStatus(r0) - return -} - -func rtlNtStatusToDosError(status ntStatus) (winerr error) { - r0, _, _ := syscall.SyscallN(procRtlNtStatusToDosErrorNoTeb.Addr(), uintptr(status)) - if r0 != 0 { - winerr = syscall.Errno(r0) - } - return -} - -func wsaGetOverlappedResult(h windows.Handle, o *windows.Overlapped, bytes *uint32, wait bool, flags *uint32) (err error) { - var _p0 uint32 - if wait { - _p0 = 1 - } - r1, _, e1 := syscall.SyscallN(procWSAGetOverlappedResult.Addr(), uintptr(h), uintptr(unsafe.Pointer(o)), uintptr(unsafe.Pointer(bytes)), uintptr(_p0), uintptr(unsafe.Pointer(flags))) - if r1 == 0 { - err = errnoErr(e1) - } - return -} diff --git a/vendor/github.com/containerd/containerd/api/LICENSE b/vendor/github.com/containerd/containerd/api/LICENSE deleted file mode 100644 index 584149b6e..000000000 --- a/vendor/github.com/containerd/containerd/api/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://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. diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go deleted file mode 100644 index aab9e45b1..000000000 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.pb.go +++ /dev/null @@ -1,1178 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/services/containers/v1/containers.proto - -package containers - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - emptypb "google.golang.org/protobuf/types/known/emptypb" - fieldmaskpb "google.golang.org/protobuf/types/known/fieldmaskpb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Container struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // ID is the user-specified identifier. - // - // This field may not be updated. - ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - // Labels provides an area to include arbitrary data on containers. - // - // The combined size of a key/value pair cannot exceed 4096 bytes. - // - // Note that to add a new value to this field, read the existing set and - // include the entire result in the update call. - Labels map[string]string `protobuf:"bytes,2,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // Image contains the reference of the image used to build the - // specification and snapshots for running this container. - // - // If this field is updated, the spec and rootfs needed to updated, as well. - Image string `protobuf:"bytes,3,opt,name=image,proto3" json:"image,omitempty"` - // Runtime specifies which runtime to use for executing this container. - Runtime *Container_Runtime `protobuf:"bytes,4,opt,name=runtime,proto3" json:"runtime,omitempty"` - // Spec to be used when creating the container. This is runtime specific. - Spec *anypb.Any `protobuf:"bytes,5,opt,name=spec,proto3" json:"spec,omitempty"` - // Snapshotter specifies the snapshotter name used for rootfs - Snapshotter string `protobuf:"bytes,6,opt,name=snapshotter,proto3" json:"snapshotter,omitempty"` - // SnapshotKey specifies the snapshot key to use for the container's root - // filesystem. When starting a task from this container, a caller should - // look up the mounts from the snapshot service and include those on the - // task create request. - // - // Snapshots referenced in this field will not be garbage collected. - // - // This field is set to empty when the rootfs is not a snapshot. - // - // This field may be updated. - SnapshotKey string `protobuf:"bytes,7,opt,name=snapshot_key,json=snapshotKey,proto3" json:"snapshot_key,omitempty"` - // CreatedAt is the time the container was first created. - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,8,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - // UpdatedAt is the last time the container was mutated. - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,9,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` - // Extensions allow clients to provide zero or more blobs that are directly - // associated with the container. One may provide protobuf, json, or other - // encoding formats. The primary use of this is to further decorate the - // container object with fields that may be specific to a client integration. - // - // The key portion of this map should identify a "name" for the extension - // that should be unique against other extensions. When updating extension - // data, one should only update the specified extension using field paths - // to select a specific map key. - Extensions map[string]*anypb.Any `protobuf:"bytes,10,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // Sandbox ID this container belongs to. - Sandbox string `protobuf:"bytes,11,opt,name=sandbox,proto3" json:"sandbox,omitempty"` -} - -func (x *Container) Reset() { - *x = Container{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Container) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Container) ProtoMessage() {} - -func (x *Container) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Container.ProtoReflect.Descriptor instead. -func (*Container) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{0} -} - -func (x *Container) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *Container) GetLabels() map[string]string { - if x != nil { - return x.Labels - } - return nil -} - -func (x *Container) GetImage() string { - if x != nil { - return x.Image - } - return "" -} - -func (x *Container) GetRuntime() *Container_Runtime { - if x != nil { - return x.Runtime - } - return nil -} - -func (x *Container) GetSpec() *anypb.Any { - if x != nil { - return x.Spec - } - return nil -} - -func (x *Container) GetSnapshotter() string { - if x != nil { - return x.Snapshotter - } - return "" -} - -func (x *Container) GetSnapshotKey() string { - if x != nil { - return x.SnapshotKey - } - return "" -} - -func (x *Container) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *Container) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -func (x *Container) GetExtensions() map[string]*anypb.Any { - if x != nil { - return x.Extensions - } - return nil -} - -func (x *Container) GetSandbox() string { - if x != nil { - return x.Sandbox - } - return "" -} - -type GetContainerRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *GetContainerRequest) Reset() { - *x = GetContainerRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetContainerRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetContainerRequest) ProtoMessage() {} - -func (x *GetContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetContainerRequest.ProtoReflect.Descriptor instead. -func (*GetContainerRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{1} -} - -func (x *GetContainerRequest) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -type GetContainerResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Container *Container `protobuf:"bytes,1,opt,name=container,proto3" json:"container,omitempty"` -} - -func (x *GetContainerResponse) Reset() { - *x = GetContainerResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetContainerResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetContainerResponse) ProtoMessage() {} - -func (x *GetContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetContainerResponse.ProtoReflect.Descriptor instead. -func (*GetContainerResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{2} -} - -func (x *GetContainerResponse) GetContainer() *Container { - if x != nil { - return x.Container - } - return nil -} - -type ListContainersRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Filters contains one or more filters using the syntax defined in the - // containerd filter package. - // - // The returned result will be those that match any of the provided - // filters. Expanded, containers that match the following will be - // returned: - // - // filters[0] or filters[1] or ... or filters[n-1] or filters[n] - // - // If filters is zero-length or nil, all items will be returned. - Filters []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"` -} - -func (x *ListContainersRequest) Reset() { - *x = ListContainersRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListContainersRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListContainersRequest) ProtoMessage() {} - -func (x *ListContainersRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListContainersRequest.ProtoReflect.Descriptor instead. -func (*ListContainersRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{3} -} - -func (x *ListContainersRequest) GetFilters() []string { - if x != nil { - return x.Filters - } - return nil -} - -type ListContainersResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Containers []*Container `protobuf:"bytes,1,rep,name=containers,proto3" json:"containers,omitempty"` -} - -func (x *ListContainersResponse) Reset() { - *x = ListContainersResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListContainersResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListContainersResponse) ProtoMessage() {} - -func (x *ListContainersResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListContainersResponse.ProtoReflect.Descriptor instead. -func (*ListContainersResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{4} -} - -func (x *ListContainersResponse) GetContainers() []*Container { - if x != nil { - return x.Containers - } - return nil -} - -type CreateContainerRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Container *Container `protobuf:"bytes,1,opt,name=container,proto3" json:"container,omitempty"` -} - -func (x *CreateContainerRequest) Reset() { - *x = CreateContainerRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateContainerRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateContainerRequest) ProtoMessage() {} - -func (x *CreateContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateContainerRequest.ProtoReflect.Descriptor instead. -func (*CreateContainerRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{5} -} - -func (x *CreateContainerRequest) GetContainer() *Container { - if x != nil { - return x.Container - } - return nil -} - -type CreateContainerResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Container *Container `protobuf:"bytes,1,opt,name=container,proto3" json:"container,omitempty"` -} - -func (x *CreateContainerResponse) Reset() { - *x = CreateContainerResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateContainerResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateContainerResponse) ProtoMessage() {} - -func (x *CreateContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateContainerResponse.ProtoReflect.Descriptor instead. -func (*CreateContainerResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{6} -} - -func (x *CreateContainerResponse) GetContainer() *Container { - if x != nil { - return x.Container - } - return nil -} - -// UpdateContainerRequest updates the metadata on one or more container. -// -// The operation should follow semantics described in -// https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/field-mask, -// unless otherwise qualified. -type UpdateContainerRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Container provides the target values, as declared by the mask, for the update. - // - // The ID field must be set. - Container *Container `protobuf:"bytes,1,opt,name=container,proto3" json:"container,omitempty"` - // UpdateMask specifies which fields to perform the update on. If empty, - // the operation applies to all fields. - UpdateMask *fieldmaskpb.FieldMask `protobuf:"bytes,2,opt,name=update_mask,json=updateMask,proto3" json:"update_mask,omitempty"` -} - -func (x *UpdateContainerRequest) Reset() { - *x = UpdateContainerRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateContainerRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateContainerRequest) ProtoMessage() {} - -func (x *UpdateContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateContainerRequest.ProtoReflect.Descriptor instead. -func (*UpdateContainerRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{7} -} - -func (x *UpdateContainerRequest) GetContainer() *Container { - if x != nil { - return x.Container - } - return nil -} - -func (x *UpdateContainerRequest) GetUpdateMask() *fieldmaskpb.FieldMask { - if x != nil { - return x.UpdateMask - } - return nil -} - -type UpdateContainerResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Container *Container `protobuf:"bytes,1,opt,name=container,proto3" json:"container,omitempty"` -} - -func (x *UpdateContainerResponse) Reset() { - *x = UpdateContainerResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateContainerResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateContainerResponse) ProtoMessage() {} - -func (x *UpdateContainerResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateContainerResponse.ProtoReflect.Descriptor instead. -func (*UpdateContainerResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{8} -} - -func (x *UpdateContainerResponse) GetContainer() *Container { - if x != nil { - return x.Container - } - return nil -} - -type DeleteContainerRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` -} - -func (x *DeleteContainerRequest) Reset() { - *x = DeleteContainerRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteContainerRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteContainerRequest) ProtoMessage() {} - -func (x *DeleteContainerRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteContainerRequest.ProtoReflect.Descriptor instead. -func (*DeleteContainerRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{9} -} - -func (x *DeleteContainerRequest) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -type ListContainerMessage struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Container *Container `protobuf:"bytes,1,opt,name=container,proto3" json:"container,omitempty"` -} - -func (x *ListContainerMessage) Reset() { - *x = ListContainerMessage{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListContainerMessage) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListContainerMessage) ProtoMessage() {} - -func (x *ListContainerMessage) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListContainerMessage.ProtoReflect.Descriptor instead. -func (*ListContainerMessage) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{10} -} - -func (x *ListContainerMessage) GetContainer() *Container { - if x != nil { - return x.Container - } - return nil -} - -type Container_Runtime struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Name is the name of the runtime. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Options specify additional runtime initialization options. - Options *anypb.Any `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` -} - -func (x *Container_Runtime) Reset() { - *x = Container_Runtime{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Container_Runtime) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Container_Runtime) ProtoMessage() {} - -func (x *Container_Runtime) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Container_Runtime.ProtoReflect.Descriptor instead. -func (*Container_Runtime) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP(), []int{0, 1} -} - -func (x *Container_Runtime) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Container_Runtime) GetOptions() *anypb.Any { - if x != nil { - return x.Options - } - return nil -} - -var File_github_com_containerd_containerd_api_services_containers_v1_containers_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDesc = []byte{ - 0x0a, 0x4c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x21, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, - 0x31, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, - 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, - 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8f, 0x06, 0x0a, - 0x09, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x50, 0x0a, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x14, 0x0a, 0x05, - 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x12, 0x4e, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, - 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x20, 0x0a, 0x0b, - 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x74, 0x65, 0x72, 0x12, 0x21, - 0x0a, 0x0c, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x68, 0x6f, 0x74, 0x4b, 0x65, - 0x79, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, - 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x5c, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x1a, - 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x4d, 0x0a, 0x07, 0x52, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x6f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, - 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x53, 0x0a, 0x0f, 0x45, 0x78, 0x74, - 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x25, - 0x0a, 0x13, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x62, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, - 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x31, 0x0a, 0x15, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x09, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x66, 0x0a, 0x16, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x73, 0x22, 0x64, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4a, - 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, - 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x65, 0x0a, 0x17, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x22, 0xa1, 0x01, 0x0a, 0x16, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4a, 0x0a, 0x09, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x46, 0x69, 0x65, 0x6c, 0x64, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x65, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x4a, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x28, 0x0a, 0x16, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x62, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x4a, - 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, - 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x32, 0xe4, 0x05, 0x0a, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x76, 0x0a, 0x03, 0x47, 0x65, 0x74, - 0x12, 0x36, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x7b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x38, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x39, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x81, - 0x01, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x38, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, - 0x30, 0x01, 0x12, 0x7f, 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x39, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x7f, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x39, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x3a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x39, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x2f, 0x76, 0x31, - 0x3b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescData = file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes = make([]protoimpl.MessageInfo, 14) -var file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_goTypes = []interface{}{ - (*Container)(nil), // 0: containerd.services.containers.v1.Container - (*GetContainerRequest)(nil), // 1: containerd.services.containers.v1.GetContainerRequest - (*GetContainerResponse)(nil), // 2: containerd.services.containers.v1.GetContainerResponse - (*ListContainersRequest)(nil), // 3: containerd.services.containers.v1.ListContainersRequest - (*ListContainersResponse)(nil), // 4: containerd.services.containers.v1.ListContainersResponse - (*CreateContainerRequest)(nil), // 5: containerd.services.containers.v1.CreateContainerRequest - (*CreateContainerResponse)(nil), // 6: containerd.services.containers.v1.CreateContainerResponse - (*UpdateContainerRequest)(nil), // 7: containerd.services.containers.v1.UpdateContainerRequest - (*UpdateContainerResponse)(nil), // 8: containerd.services.containers.v1.UpdateContainerResponse - (*DeleteContainerRequest)(nil), // 9: containerd.services.containers.v1.DeleteContainerRequest - (*ListContainerMessage)(nil), // 10: containerd.services.containers.v1.ListContainerMessage - nil, // 11: containerd.services.containers.v1.Container.LabelsEntry - (*Container_Runtime)(nil), // 12: containerd.services.containers.v1.Container.Runtime - nil, // 13: containerd.services.containers.v1.Container.ExtensionsEntry - (*anypb.Any)(nil), // 14: google.protobuf.Any - (*timestamppb.Timestamp)(nil), // 15: google.protobuf.Timestamp - (*fieldmaskpb.FieldMask)(nil), // 16: google.protobuf.FieldMask - (*emptypb.Empty)(nil), // 17: google.protobuf.Empty -} -var file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_depIdxs = []int32{ - 11, // 0: containerd.services.containers.v1.Container.labels:type_name -> containerd.services.containers.v1.Container.LabelsEntry - 12, // 1: containerd.services.containers.v1.Container.runtime:type_name -> containerd.services.containers.v1.Container.Runtime - 14, // 2: containerd.services.containers.v1.Container.spec:type_name -> google.protobuf.Any - 15, // 3: containerd.services.containers.v1.Container.created_at:type_name -> google.protobuf.Timestamp - 15, // 4: containerd.services.containers.v1.Container.updated_at:type_name -> google.protobuf.Timestamp - 13, // 5: containerd.services.containers.v1.Container.extensions:type_name -> containerd.services.containers.v1.Container.ExtensionsEntry - 0, // 6: containerd.services.containers.v1.GetContainerResponse.container:type_name -> containerd.services.containers.v1.Container - 0, // 7: containerd.services.containers.v1.ListContainersResponse.containers:type_name -> containerd.services.containers.v1.Container - 0, // 8: containerd.services.containers.v1.CreateContainerRequest.container:type_name -> containerd.services.containers.v1.Container - 0, // 9: containerd.services.containers.v1.CreateContainerResponse.container:type_name -> containerd.services.containers.v1.Container - 0, // 10: containerd.services.containers.v1.UpdateContainerRequest.container:type_name -> containerd.services.containers.v1.Container - 16, // 11: containerd.services.containers.v1.UpdateContainerRequest.update_mask:type_name -> google.protobuf.FieldMask - 0, // 12: containerd.services.containers.v1.UpdateContainerResponse.container:type_name -> containerd.services.containers.v1.Container - 0, // 13: containerd.services.containers.v1.ListContainerMessage.container:type_name -> containerd.services.containers.v1.Container - 14, // 14: containerd.services.containers.v1.Container.Runtime.options:type_name -> google.protobuf.Any - 14, // 15: containerd.services.containers.v1.Container.ExtensionsEntry.value:type_name -> google.protobuf.Any - 1, // 16: containerd.services.containers.v1.Containers.Get:input_type -> containerd.services.containers.v1.GetContainerRequest - 3, // 17: containerd.services.containers.v1.Containers.List:input_type -> containerd.services.containers.v1.ListContainersRequest - 3, // 18: containerd.services.containers.v1.Containers.ListStream:input_type -> containerd.services.containers.v1.ListContainersRequest - 5, // 19: containerd.services.containers.v1.Containers.Create:input_type -> containerd.services.containers.v1.CreateContainerRequest - 7, // 20: containerd.services.containers.v1.Containers.Update:input_type -> containerd.services.containers.v1.UpdateContainerRequest - 9, // 21: containerd.services.containers.v1.Containers.Delete:input_type -> containerd.services.containers.v1.DeleteContainerRequest - 2, // 22: containerd.services.containers.v1.Containers.Get:output_type -> containerd.services.containers.v1.GetContainerResponse - 4, // 23: containerd.services.containers.v1.Containers.List:output_type -> containerd.services.containers.v1.ListContainersResponse - 10, // 24: containerd.services.containers.v1.Containers.ListStream:output_type -> containerd.services.containers.v1.ListContainerMessage - 6, // 25: containerd.services.containers.v1.Containers.Create:output_type -> containerd.services.containers.v1.CreateContainerResponse - 8, // 26: containerd.services.containers.v1.Containers.Update:output_type -> containerd.services.containers.v1.UpdateContainerResponse - 17, // 27: containerd.services.containers.v1.Containers.Delete:output_type -> google.protobuf.Empty - 22, // [22:28] is the sub-list for method output_type - 16, // [16:22] is the sub-list for method input_type - 16, // [16:16] is the sub-list for extension type_name - 16, // [16:16] is the sub-list for extension extendee - 0, // [0:16] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_init() } -func file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_init() { - if File_github_com_containerd_containerd_api_services_containers_v1_containers_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Container); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetContainerRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetContainerResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListContainersRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListContainersResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateContainerRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateContainerResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateContainerRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateContainerResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteContainerRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListContainerMessage); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Container_Runtime); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDesc, - NumEnums: 0, - NumMessages: 14, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_services_containers_v1_containers_proto = out.File - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_rawDesc = nil - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_goTypes = nil - file_github_com_containerd_containerd_api_services_containers_v1_containers_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto deleted file mode 100644 index 3de07ffbd..000000000 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers.proto +++ /dev/null @@ -1,181 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.services.containers.v1; - -import "google/protobuf/any.proto"; -import "google/protobuf/empty.proto"; -import "google/protobuf/field_mask.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/containerd/containerd/api/services/containers/v1;containers"; - -// Containers provides metadata storage for containers used in the execution -// service. -// -// The objects here provide an state-independent view of containers for use in -// management and resource pinning. From that perspective, containers do not -// have a "state" but rather this is the set of resources that will be -// considered in use by the container. -// -// From the perspective of the execution service, these objects represent the -// base parameters for creating a container process. -// -// In general, when looking to add fields for this type, first ask yourself -// whether or not the function of the field has to do with runtime execution or -// is invariant of the runtime state of the container. If it has to do with -// runtime, or changes as the "container" is started and stops, it probably -// doesn't belong on this object. -service Containers { - rpc Get(GetContainerRequest) returns (GetContainerResponse); - rpc List(ListContainersRequest) returns (ListContainersResponse); - rpc ListStream(ListContainersRequest) returns (stream ListContainerMessage); - rpc Create(CreateContainerRequest) returns (CreateContainerResponse); - rpc Update(UpdateContainerRequest) returns (UpdateContainerResponse); - rpc Delete(DeleteContainerRequest) returns (google.protobuf.Empty); -} - -message Container { - // ID is the user-specified identifier. - // - // This field may not be updated. - string id = 1; - - // Labels provides an area to include arbitrary data on containers. - // - // The combined size of a key/value pair cannot exceed 4096 bytes. - // - // Note that to add a new value to this field, read the existing set and - // include the entire result in the update call. - map labels = 2; - - // Image contains the reference of the image used to build the - // specification and snapshots for running this container. - // - // If this field is updated, the spec and rootfs needed to updated, as well. - string image = 3; - - message Runtime { - // Name is the name of the runtime. - string name = 1; - // Options specify additional runtime initialization options. - google.protobuf.Any options = 2; - } - // Runtime specifies which runtime to use for executing this container. - Runtime runtime = 4; - - // Spec to be used when creating the container. This is runtime specific. - google.protobuf.Any spec = 5; - - // Snapshotter specifies the snapshotter name used for rootfs - string snapshotter = 6; - - // SnapshotKey specifies the snapshot key to use for the container's root - // filesystem. When starting a task from this container, a caller should - // look up the mounts from the snapshot service and include those on the - // task create request. - // - // Snapshots referenced in this field will not be garbage collected. - // - // This field is set to empty when the rootfs is not a snapshot. - // - // This field may be updated. - string snapshot_key = 7; - - // CreatedAt is the time the container was first created. - google.protobuf.Timestamp created_at = 8; - - // UpdatedAt is the last time the container was mutated. - google.protobuf.Timestamp updated_at = 9; - - // Extensions allow clients to provide zero or more blobs that are directly - // associated with the container. One may provide protobuf, json, or other - // encoding formats. The primary use of this is to further decorate the - // container object with fields that may be specific to a client integration. - // - // The key portion of this map should identify a "name" for the extension - // that should be unique against other extensions. When updating extension - // data, one should only update the specified extension using field paths - // to select a specific map key. - map extensions = 10; - - // Sandbox ID this container belongs to. - string sandbox = 11; -} - -message GetContainerRequest { - string id = 1; -} - -message GetContainerResponse { - Container container = 1; -} - -message ListContainersRequest { - // Filters contains one or more filters using the syntax defined in the - // containerd filter package. - // - // The returned result will be those that match any of the provided - // filters. Expanded, containers that match the following will be - // returned: - // - // filters[0] or filters[1] or ... or filters[n-1] or filters[n] - // - // If filters is zero-length or nil, all items will be returned. - repeated string filters = 1; -} - -message ListContainersResponse { - repeated Container containers = 1; -} - -message CreateContainerRequest { - Container container = 1; -} - -message CreateContainerResponse { - Container container = 1; -} - -// UpdateContainerRequest updates the metadata on one or more container. -// -// The operation should follow semantics described in -// https://developers.google.com/protocol-buffers/docs/reference/csharp/class/google/protobuf/well-known-types/field-mask, -// unless otherwise qualified. -message UpdateContainerRequest { - // Container provides the target values, as declared by the mask, for the update. - // - // The ID field must be set. - Container container = 1; - - // UpdateMask specifies which fields to perform the update on. If empty, - // the operation applies to all fields. - google.protobuf.FieldMask update_mask = 2; -} - -message UpdateContainerResponse { - Container container = 1; -} - -message DeleteContainerRequest { - string id = 1; -} - -message ListContainerMessage { - Container container = 1; -} diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers_grpc.pb.go b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers_grpc.pb.go deleted file mode 100644 index 93dab77d1..000000000 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers_grpc.pb.go +++ /dev/null @@ -1,316 +0,0 @@ -//go:build !no_grpc - -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.20.1 -// source: github.com/containerd/containerd/api/services/containers/v1/containers.proto - -package containers - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// ContainersClient is the client API for Containers service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type ContainersClient interface { - Get(ctx context.Context, in *GetContainerRequest, opts ...grpc.CallOption) (*GetContainerResponse, error) - List(ctx context.Context, in *ListContainersRequest, opts ...grpc.CallOption) (*ListContainersResponse, error) - ListStream(ctx context.Context, in *ListContainersRequest, opts ...grpc.CallOption) (Containers_ListStreamClient, error) - Create(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) - Update(ctx context.Context, in *UpdateContainerRequest, opts ...grpc.CallOption) (*UpdateContainerResponse, error) - Delete(ctx context.Context, in *DeleteContainerRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) -} - -type containersClient struct { - cc grpc.ClientConnInterface -} - -func NewContainersClient(cc grpc.ClientConnInterface) ContainersClient { - return &containersClient{cc} -} - -func (c *containersClient) Get(ctx context.Context, in *GetContainerRequest, opts ...grpc.CallOption) (*GetContainerResponse, error) { - out := new(GetContainerResponse) - err := c.cc.Invoke(ctx, "/containerd.services.containers.v1.Containers/Get", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *containersClient) List(ctx context.Context, in *ListContainersRequest, opts ...grpc.CallOption) (*ListContainersResponse, error) { - out := new(ListContainersResponse) - err := c.cc.Invoke(ctx, "/containerd.services.containers.v1.Containers/List", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *containersClient) ListStream(ctx context.Context, in *ListContainersRequest, opts ...grpc.CallOption) (Containers_ListStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &Containers_ServiceDesc.Streams[0], "/containerd.services.containers.v1.Containers/ListStream", opts...) - if err != nil { - return nil, err - } - x := &containersListStreamClient{stream} - if err := x.ClientStream.SendMsg(in); err != nil { - return nil, err - } - if err := x.ClientStream.CloseSend(); err != nil { - return nil, err - } - return x, nil -} - -type Containers_ListStreamClient interface { - Recv() (*ListContainerMessage, error) - grpc.ClientStream -} - -type containersListStreamClient struct { - grpc.ClientStream -} - -func (x *containersListStreamClient) Recv() (*ListContainerMessage, error) { - m := new(ListContainerMessage) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *containersClient) Create(ctx context.Context, in *CreateContainerRequest, opts ...grpc.CallOption) (*CreateContainerResponse, error) { - out := new(CreateContainerResponse) - err := c.cc.Invoke(ctx, "/containerd.services.containers.v1.Containers/Create", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *containersClient) Update(ctx context.Context, in *UpdateContainerRequest, opts ...grpc.CallOption) (*UpdateContainerResponse, error) { - out := new(UpdateContainerResponse) - err := c.cc.Invoke(ctx, "/containerd.services.containers.v1.Containers/Update", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *containersClient) Delete(ctx context.Context, in *DeleteContainerRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.containers.v1.Containers/Delete", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// ContainersServer is the server API for Containers service. -// All implementations must embed UnimplementedContainersServer -// for forward compatibility -type ContainersServer interface { - Get(context.Context, *GetContainerRequest) (*GetContainerResponse, error) - List(context.Context, *ListContainersRequest) (*ListContainersResponse, error) - ListStream(*ListContainersRequest, Containers_ListStreamServer) error - Create(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) - Update(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error) - Delete(context.Context, *DeleteContainerRequest) (*emptypb.Empty, error) - mustEmbedUnimplementedContainersServer() -} - -// UnimplementedContainersServer must be embedded to have forward compatible implementations. -type UnimplementedContainersServer struct { -} - -func (UnimplementedContainersServer) Get(context.Context, *GetContainerRequest) (*GetContainerResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") -} -func (UnimplementedContainersServer) List(context.Context, *ListContainersRequest) (*ListContainersResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method List not implemented") -} -func (UnimplementedContainersServer) ListStream(*ListContainersRequest, Containers_ListStreamServer) error { - return status.Errorf(codes.Unimplemented, "method ListStream not implemented") -} -func (UnimplementedContainersServer) Create(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") -} -func (UnimplementedContainersServer) Update(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") -} -func (UnimplementedContainersServer) Delete(context.Context, *DeleteContainerRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") -} -func (UnimplementedContainersServer) mustEmbedUnimplementedContainersServer() {} - -// UnsafeContainersServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to ContainersServer will -// result in compilation errors. -type UnsafeContainersServer interface { - mustEmbedUnimplementedContainersServer() -} - -func RegisterContainersServer(s grpc.ServiceRegistrar, srv ContainersServer) { - s.RegisterService(&Containers_ServiceDesc, srv) -} - -func _Containers_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetContainerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ContainersServer).Get(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.containers.v1.Containers/Get", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ContainersServer).Get(ctx, req.(*GetContainerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Containers_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListContainersRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ContainersServer).List(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.containers.v1.Containers/List", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ContainersServer).List(ctx, req.(*ListContainersRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Containers_ListStream_Handler(srv interface{}, stream grpc.ServerStream) error { - m := new(ListContainersRequest) - if err := stream.RecvMsg(m); err != nil { - return err - } - return srv.(ContainersServer).ListStream(m, &containersListStreamServer{stream}) -} - -type Containers_ListStreamServer interface { - Send(*ListContainerMessage) error - grpc.ServerStream -} - -type containersListStreamServer struct { - grpc.ServerStream -} - -func (x *containersListStreamServer) Send(m *ListContainerMessage) error { - return x.ServerStream.SendMsg(m) -} - -func _Containers_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateContainerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ContainersServer).Create(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.containers.v1.Containers/Create", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ContainersServer).Create(ctx, req.(*CreateContainerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Containers_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateContainerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ContainersServer).Update(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.containers.v1.Containers/Update", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ContainersServer).Update(ctx, req.(*UpdateContainerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Containers_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteContainerRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ContainersServer).Delete(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.containers.v1.Containers/Delete", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ContainersServer).Delete(ctx, req.(*DeleteContainerRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// Containers_ServiceDesc is the grpc.ServiceDesc for Containers service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Containers_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "containerd.services.containers.v1.Containers", - HandlerType: (*ContainersServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Get", - Handler: _Containers_Get_Handler, - }, - { - MethodName: "List", - Handler: _Containers_List_Handler, - }, - { - MethodName: "Create", - Handler: _Containers_Create_Handler, - }, - { - MethodName: "Update", - Handler: _Containers_Update_Handler, - }, - { - MethodName: "Delete", - Handler: _Containers_Delete_Handler, - }, - }, - Streams: []grpc.StreamDesc{ - { - StreamName: "ListStream", - Handler: _Containers_ListStream_Handler, - ServerStreams: true, - }, - }, - Metadata: "github.com/containerd/containerd/api/services/containers/v1/containers.proto", -} diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers_ttrpc.pb.go b/vendor/github.com/containerd/containerd/api/services/containers/v1/containers_ttrpc.pb.go deleted file mode 100644 index 8090011df..000000000 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/containers_ttrpc.pb.go +++ /dev/null @@ -1,174 +0,0 @@ -// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT. -// source: github.com/containerd/containerd/api/services/containers/v1/containers.proto -package containers - -import ( - context "context" - ttrpc "github.com/containerd/ttrpc" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -type TTRPCContainersService interface { - Get(context.Context, *GetContainerRequest) (*GetContainerResponse, error) - List(context.Context, *ListContainersRequest) (*ListContainersResponse, error) - ListStream(context.Context, *ListContainersRequest, TTRPCContainers_ListStreamServer) error - Create(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) - Update(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error) - Delete(context.Context, *DeleteContainerRequest) (*emptypb.Empty, error) -} - -type TTRPCContainers_ListStreamServer interface { - Send(*ListContainerMessage) error - ttrpc.StreamServer -} - -type ttrpccontainersListStreamServer struct { - ttrpc.StreamServer -} - -func (x *ttrpccontainersListStreamServer) Send(m *ListContainerMessage) error { - return x.StreamServer.SendMsg(m) -} - -func RegisterTTRPCContainersService(srv *ttrpc.Server, svc TTRPCContainersService) { - srv.RegisterService("containerd.services.containers.v1.Containers", &ttrpc.ServiceDesc{ - Methods: map[string]ttrpc.Method{ - "Get": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req GetContainerRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Get(ctx, &req) - }, - "List": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req ListContainersRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.List(ctx, &req) - }, - "Create": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req CreateContainerRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Create(ctx, &req) - }, - "Update": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req UpdateContainerRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Update(ctx, &req) - }, - "Delete": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req DeleteContainerRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Delete(ctx, &req) - }, - }, - Streams: map[string]ttrpc.Stream{ - "ListStream": { - Handler: func(ctx context.Context, stream ttrpc.StreamServer) (interface{}, error) { - m := new(ListContainersRequest) - if err := stream.RecvMsg(m); err != nil { - return nil, err - } - return nil, svc.ListStream(ctx, m, &ttrpccontainersListStreamServer{stream}) - }, - StreamingClient: false, - StreamingServer: true, - }, - }, - }) -} - -type TTRPCContainersClient interface { - Get(context.Context, *GetContainerRequest) (*GetContainerResponse, error) - List(context.Context, *ListContainersRequest) (*ListContainersResponse, error) - ListStream(context.Context, *ListContainersRequest) (TTRPCContainers_ListStreamClient, error) - Create(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error) - Update(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error) - Delete(context.Context, *DeleteContainerRequest) (*emptypb.Empty, error) -} - -type ttrpccontainersClient struct { - client *ttrpc.Client -} - -func NewTTRPCContainersClient(client *ttrpc.Client) TTRPCContainersClient { - return &ttrpccontainersClient{ - client: client, - } -} - -func (c *ttrpccontainersClient) Get(ctx context.Context, req *GetContainerRequest) (*GetContainerResponse, error) { - var resp GetContainerResponse - if err := c.client.Call(ctx, "containerd.services.containers.v1.Containers", "Get", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpccontainersClient) List(ctx context.Context, req *ListContainersRequest) (*ListContainersResponse, error) { - var resp ListContainersResponse - if err := c.client.Call(ctx, "containerd.services.containers.v1.Containers", "List", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpccontainersClient) ListStream(ctx context.Context, req *ListContainersRequest) (TTRPCContainers_ListStreamClient, error) { - stream, err := c.client.NewStream(ctx, &ttrpc.StreamDesc{ - StreamingClient: false, - StreamingServer: true, - }, "containerd.services.containers.v1.Containers", "ListStream", req) - if err != nil { - return nil, err - } - x := &ttrpccontainersListStreamClient{stream} - return x, nil -} - -type TTRPCContainers_ListStreamClient interface { - Recv() (*ListContainerMessage, error) - ttrpc.ClientStream -} - -type ttrpccontainersListStreamClient struct { - ttrpc.ClientStream -} - -func (x *ttrpccontainersListStreamClient) Recv() (*ListContainerMessage, error) { - m := new(ListContainerMessage) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} - -func (c *ttrpccontainersClient) Create(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) { - var resp CreateContainerResponse - if err := c.client.Call(ctx, "containerd.services.containers.v1.Containers", "Create", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpccontainersClient) Update(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) { - var resp UpdateContainerResponse - if err := c.client.Call(ctx, "containerd.services.containers.v1.Containers", "Update", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpccontainersClient) Delete(ctx context.Context, req *DeleteContainerRequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.containers.v1.Containers", "Delete", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} diff --git a/vendor/github.com/containerd/containerd/api/services/containers/v1/doc.go b/vendor/github.com/containerd/containerd/api/services/containers/v1/doc.go deleted file mode 100644 index a6ef491ce..000000000 --- a/vendor/github.com/containerd/containerd/api/services/containers/v1/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package containers diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/doc.go b/vendor/github.com/containerd/containerd/api/services/tasks/v1/doc.go deleted file mode 100644 index 0888ba8a8..000000000 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package tasks diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go deleted file mode 100644 index 1a55d696d..000000000 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.pb.go +++ /dev/null @@ -1,2359 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/services/tasks/v1/tasks.proto - -package tasks - -import ( - types "github.com/containerd/containerd/api/types" - task "github.com/containerd/containerd/api/types/task" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - emptypb "google.golang.org/protobuf/types/known/emptypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type CreateTaskRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - // RootFS provides the pre-chroot mounts to perform in the shim before - // executing the container task. - // - // These are for mounts that cannot be performed in the user namespace. - // Typically, these mounts should be resolved from snapshots specified on - // the container object. - Rootfs []*types.Mount `protobuf:"bytes,3,rep,name=rootfs,proto3" json:"rootfs,omitempty"` - Stdin string `protobuf:"bytes,4,opt,name=stdin,proto3" json:"stdin,omitempty"` - Stdout string `protobuf:"bytes,5,opt,name=stdout,proto3" json:"stdout,omitempty"` - Stderr string `protobuf:"bytes,6,opt,name=stderr,proto3" json:"stderr,omitempty"` - Terminal bool `protobuf:"varint,7,opt,name=terminal,proto3" json:"terminal,omitempty"` - Checkpoint *types.Descriptor `protobuf:"bytes,8,opt,name=checkpoint,proto3" json:"checkpoint,omitempty"` - Options *anypb.Any `protobuf:"bytes,9,opt,name=options,proto3" json:"options,omitempty"` - RuntimePath string `protobuf:"bytes,10,opt,name=runtime_path,json=runtimePath,proto3" json:"runtime_path,omitempty"` -} - -func (x *CreateTaskRequest) Reset() { - *x = CreateTaskRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateTaskRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateTaskRequest) ProtoMessage() {} - -func (x *CreateTaskRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateTaskRequest.ProtoReflect.Descriptor instead. -func (*CreateTaskRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{0} -} - -func (x *CreateTaskRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *CreateTaskRequest) GetRootfs() []*types.Mount { - if x != nil { - return x.Rootfs - } - return nil -} - -func (x *CreateTaskRequest) GetStdin() string { - if x != nil { - return x.Stdin - } - return "" -} - -func (x *CreateTaskRequest) GetStdout() string { - if x != nil { - return x.Stdout - } - return "" -} - -func (x *CreateTaskRequest) GetStderr() string { - if x != nil { - return x.Stderr - } - return "" -} - -func (x *CreateTaskRequest) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -func (x *CreateTaskRequest) GetCheckpoint() *types.Descriptor { - if x != nil { - return x.Checkpoint - } - return nil -} - -func (x *CreateTaskRequest) GetOptions() *anypb.Any { - if x != nil { - return x.Options - } - return nil -} - -func (x *CreateTaskRequest) GetRuntimePath() string { - if x != nil { - return x.RuntimePath - } - return "" -} - -type CreateTaskResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` -} - -func (x *CreateTaskResponse) Reset() { - *x = CreateTaskResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CreateTaskResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CreateTaskResponse) ProtoMessage() {} - -func (x *CreateTaskResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CreateTaskResponse.ProtoReflect.Descriptor instead. -func (*CreateTaskResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{1} -} - -func (x *CreateTaskResponse) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *CreateTaskResponse) GetPid() uint32 { - if x != nil { - return x.Pid - } - return 0 -} - -type StartRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` -} - -func (x *StartRequest) Reset() { - *x = StartRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StartRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StartRequest) ProtoMessage() {} - -func (x *StartRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StartRequest.ProtoReflect.Descriptor instead. -func (*StartRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{2} -} - -func (x *StartRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *StartRequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -type StartResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Pid uint32 `protobuf:"varint,1,opt,name=pid,proto3" json:"pid,omitempty"` -} - -func (x *StartResponse) Reset() { - *x = StartResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StartResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StartResponse) ProtoMessage() {} - -func (x *StartResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StartResponse.ProtoReflect.Descriptor instead. -func (*StartResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{3} -} - -func (x *StartResponse) GetPid() uint32 { - if x != nil { - return x.Pid - } - return 0 -} - -type DeleteTaskRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` -} - -func (x *DeleteTaskRequest) Reset() { - *x = DeleteTaskRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteTaskRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteTaskRequest) ProtoMessage() {} - -func (x *DeleteTaskRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteTaskRequest.ProtoReflect.Descriptor instead. -func (*DeleteTaskRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{4} -} - -func (x *DeleteTaskRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -type DeleteResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ID string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - Pid uint32 `protobuf:"varint,2,opt,name=pid,proto3" json:"pid,omitempty"` - ExitStatus uint32 `protobuf:"varint,3,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` - ExitedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=exited_at,json=exitedAt,proto3" json:"exited_at,omitempty"` -} - -func (x *DeleteResponse) Reset() { - *x = DeleteResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteResponse) ProtoMessage() {} - -func (x *DeleteResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteResponse.ProtoReflect.Descriptor instead. -func (*DeleteResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{5} -} - -func (x *DeleteResponse) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *DeleteResponse) GetPid() uint32 { - if x != nil { - return x.Pid - } - return 0 -} - -func (x *DeleteResponse) GetExitStatus() uint32 { - if x != nil { - return x.ExitStatus - } - return 0 -} - -func (x *DeleteResponse) GetExitedAt() *timestamppb.Timestamp { - if x != nil { - return x.ExitedAt - } - return nil -} - -type DeleteProcessRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` -} - -func (x *DeleteProcessRequest) Reset() { - *x = DeleteProcessRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DeleteProcessRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DeleteProcessRequest) ProtoMessage() {} - -func (x *DeleteProcessRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use DeleteProcessRequest.ProtoReflect.Descriptor instead. -func (*DeleteProcessRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{6} -} - -func (x *DeleteProcessRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *DeleteProcessRequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -type GetRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` -} - -func (x *GetRequest) Reset() { - *x = GetRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetRequest) ProtoMessage() {} - -func (x *GetRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetRequest.ProtoReflect.Descriptor instead. -func (*GetRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{7} -} - -func (x *GetRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *GetRequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -type GetResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Process *task.Process `protobuf:"bytes,1,opt,name=process,proto3" json:"process,omitempty"` -} - -func (x *GetResponse) Reset() { - *x = GetResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *GetResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*GetResponse) ProtoMessage() {} - -func (x *GetResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use GetResponse.ProtoReflect.Descriptor instead. -func (*GetResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{8} -} - -func (x *GetResponse) GetProcess() *task.Process { - if x != nil { - return x.Process - } - return nil -} - -type ListTasksRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Filter string `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` -} - -func (x *ListTasksRequest) Reset() { - *x = ListTasksRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListTasksRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListTasksRequest) ProtoMessage() {} - -func (x *ListTasksRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListTasksRequest.ProtoReflect.Descriptor instead. -func (*ListTasksRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{9} -} - -func (x *ListTasksRequest) GetFilter() string { - if x != nil { - return x.Filter - } - return "" -} - -type ListTasksResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Tasks []*task.Process `protobuf:"bytes,1,rep,name=tasks,proto3" json:"tasks,omitempty"` -} - -func (x *ListTasksResponse) Reset() { - *x = ListTasksResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListTasksResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListTasksResponse) ProtoMessage() {} - -func (x *ListTasksResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListTasksResponse.ProtoReflect.Descriptor instead. -func (*ListTasksResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{10} -} - -func (x *ListTasksResponse) GetTasks() []*task.Process { - if x != nil { - return x.Tasks - } - return nil -} - -type KillRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` - Signal uint32 `protobuf:"varint,3,opt,name=signal,proto3" json:"signal,omitempty"` - All bool `protobuf:"varint,4,opt,name=all,proto3" json:"all,omitempty"` -} - -func (x *KillRequest) Reset() { - *x = KillRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *KillRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*KillRequest) ProtoMessage() {} - -func (x *KillRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use KillRequest.ProtoReflect.Descriptor instead. -func (*KillRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{11} -} - -func (x *KillRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *KillRequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -func (x *KillRequest) GetSignal() uint32 { - if x != nil { - return x.Signal - } - return 0 -} - -func (x *KillRequest) GetAll() bool { - if x != nil { - return x.All - } - return false -} - -type ExecProcessRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - Stdin string `protobuf:"bytes,2,opt,name=stdin,proto3" json:"stdin,omitempty"` - Stdout string `protobuf:"bytes,3,opt,name=stdout,proto3" json:"stdout,omitempty"` - Stderr string `protobuf:"bytes,4,opt,name=stderr,proto3" json:"stderr,omitempty"` - Terminal bool `protobuf:"varint,5,opt,name=terminal,proto3" json:"terminal,omitempty"` - // Spec for starting a process in the target container. - // - // For runc, this is a process spec, for example. - Spec *anypb.Any `protobuf:"bytes,6,opt,name=spec,proto3" json:"spec,omitempty"` - // id of the exec process - ExecID string `protobuf:"bytes,7,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` -} - -func (x *ExecProcessRequest) Reset() { - *x = ExecProcessRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExecProcessRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecProcessRequest) ProtoMessage() {} - -func (x *ExecProcessRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExecProcessRequest.ProtoReflect.Descriptor instead. -func (*ExecProcessRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{12} -} - -func (x *ExecProcessRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *ExecProcessRequest) GetStdin() string { - if x != nil { - return x.Stdin - } - return "" -} - -func (x *ExecProcessRequest) GetStdout() string { - if x != nil { - return x.Stdout - } - return "" -} - -func (x *ExecProcessRequest) GetStderr() string { - if x != nil { - return x.Stderr - } - return "" -} - -func (x *ExecProcessRequest) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -func (x *ExecProcessRequest) GetSpec() *anypb.Any { - if x != nil { - return x.Spec - } - return nil -} - -func (x *ExecProcessRequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -type ExecProcessResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields -} - -func (x *ExecProcessResponse) Reset() { - *x = ExecProcessResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ExecProcessResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ExecProcessResponse) ProtoMessage() {} - -func (x *ExecProcessResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ExecProcessResponse.ProtoReflect.Descriptor instead. -func (*ExecProcessResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{13} -} - -type ResizePtyRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` - Width uint32 `protobuf:"varint,3,opt,name=width,proto3" json:"width,omitempty"` - Height uint32 `protobuf:"varint,4,opt,name=height,proto3" json:"height,omitempty"` -} - -func (x *ResizePtyRequest) Reset() { - *x = ResizePtyRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[14] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResizePtyRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResizePtyRequest) ProtoMessage() {} - -func (x *ResizePtyRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[14] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResizePtyRequest.ProtoReflect.Descriptor instead. -func (*ResizePtyRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{14} -} - -func (x *ResizePtyRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *ResizePtyRequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -func (x *ResizePtyRequest) GetWidth() uint32 { - if x != nil { - return x.Width - } - return 0 -} - -func (x *ResizePtyRequest) GetHeight() uint32 { - if x != nil { - return x.Height - } - return 0 -} - -type CloseIORequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` - Stdin bool `protobuf:"varint,3,opt,name=stdin,proto3" json:"stdin,omitempty"` -} - -func (x *CloseIORequest) Reset() { - *x = CloseIORequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[15] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CloseIORequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CloseIORequest) ProtoMessage() {} - -func (x *CloseIORequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[15] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CloseIORequest.ProtoReflect.Descriptor instead. -func (*CloseIORequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{15} -} - -func (x *CloseIORequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *CloseIORequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -func (x *CloseIORequest) GetStdin() bool { - if x != nil { - return x.Stdin - } - return false -} - -type PauseTaskRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` -} - -func (x *PauseTaskRequest) Reset() { - *x = PauseTaskRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[16] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *PauseTaskRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*PauseTaskRequest) ProtoMessage() {} - -func (x *PauseTaskRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[16] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use PauseTaskRequest.ProtoReflect.Descriptor instead. -func (*PauseTaskRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{16} -} - -func (x *PauseTaskRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -type ResumeTaskRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` -} - -func (x *ResumeTaskRequest) Reset() { - *x = ResumeTaskRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[17] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ResumeTaskRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ResumeTaskRequest) ProtoMessage() {} - -func (x *ResumeTaskRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[17] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ResumeTaskRequest.ProtoReflect.Descriptor instead. -func (*ResumeTaskRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{17} -} - -func (x *ResumeTaskRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -type ListPidsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` -} - -func (x *ListPidsRequest) Reset() { - *x = ListPidsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[18] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListPidsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListPidsRequest) ProtoMessage() {} - -func (x *ListPidsRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[18] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListPidsRequest.ProtoReflect.Descriptor instead. -func (*ListPidsRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{18} -} - -func (x *ListPidsRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -type ListPidsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Processes includes the process ID and additional process information - Processes []*task.ProcessInfo `protobuf:"bytes,1,rep,name=processes,proto3" json:"processes,omitempty"` -} - -func (x *ListPidsResponse) Reset() { - *x = ListPidsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[19] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ListPidsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ListPidsResponse) ProtoMessage() {} - -func (x *ListPidsResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[19] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ListPidsResponse.ProtoReflect.Descriptor instead. -func (*ListPidsResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{19} -} - -func (x *ListPidsResponse) GetProcesses() []*task.ProcessInfo { - if x != nil { - return x.Processes - } - return nil -} - -type CheckpointTaskRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ParentCheckpoint string `protobuf:"bytes,2,opt,name=parent_checkpoint,json=parentCheckpoint,proto3" json:"parent_checkpoint,omitempty"` - Options *anypb.Any `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` -} - -func (x *CheckpointTaskRequest) Reset() { - *x = CheckpointTaskRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[20] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CheckpointTaskRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CheckpointTaskRequest) ProtoMessage() {} - -func (x *CheckpointTaskRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[20] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CheckpointTaskRequest.ProtoReflect.Descriptor instead. -func (*CheckpointTaskRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{20} -} - -func (x *CheckpointTaskRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *CheckpointTaskRequest) GetParentCheckpoint() string { - if x != nil { - return x.ParentCheckpoint - } - return "" -} - -func (x *CheckpointTaskRequest) GetOptions() *anypb.Any { - if x != nil { - return x.Options - } - return nil -} - -type CheckpointTaskResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Descriptors []*types.Descriptor `protobuf:"bytes,1,rep,name=descriptors,proto3" json:"descriptors,omitempty"` -} - -func (x *CheckpointTaskResponse) Reset() { - *x = CheckpointTaskResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[21] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *CheckpointTaskResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*CheckpointTaskResponse) ProtoMessage() {} - -func (x *CheckpointTaskResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[21] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use CheckpointTaskResponse.ProtoReflect.Descriptor instead. -func (*CheckpointTaskResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{21} -} - -func (x *CheckpointTaskResponse) GetDescriptors() []*types.Descriptor { - if x != nil { - return x.Descriptors - } - return nil -} - -type UpdateTaskRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - Resources *anypb.Any `protobuf:"bytes,2,opt,name=resources,proto3" json:"resources,omitempty"` - Annotations map[string]string `protobuf:"bytes,3,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *UpdateTaskRequest) Reset() { - *x = UpdateTaskRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[22] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *UpdateTaskRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*UpdateTaskRequest) ProtoMessage() {} - -func (x *UpdateTaskRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[22] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use UpdateTaskRequest.ProtoReflect.Descriptor instead. -func (*UpdateTaskRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{22} -} - -func (x *UpdateTaskRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *UpdateTaskRequest) GetResources() *anypb.Any { - if x != nil { - return x.Resources - } - return nil -} - -func (x *UpdateTaskRequest) GetAnnotations() map[string]string { - if x != nil { - return x.Annotations - } - return nil -} - -type MetricsRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Filters []string `protobuf:"bytes,1,rep,name=filters,proto3" json:"filters,omitempty"` -} - -func (x *MetricsRequest) Reset() { - *x = MetricsRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[23] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MetricsRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MetricsRequest) ProtoMessage() {} - -func (x *MetricsRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[23] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MetricsRequest.ProtoReflect.Descriptor instead. -func (*MetricsRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{23} -} - -func (x *MetricsRequest) GetFilters() []string { - if x != nil { - return x.Filters - } - return nil -} - -type MetricsResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Metrics []*types.Metric `protobuf:"bytes,1,rep,name=metrics,proto3" json:"metrics,omitempty"` -} - -func (x *MetricsResponse) Reset() { - *x = MetricsResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[24] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *MetricsResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*MetricsResponse) ProtoMessage() {} - -func (x *MetricsResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[24] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use MetricsResponse.ProtoReflect.Descriptor instead. -func (*MetricsResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{24} -} - -func (x *MetricsResponse) GetMetrics() []*types.Metric { - if x != nil { - return x.Metrics - } - return nil -} - -type WaitRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ExecID string `protobuf:"bytes,2,opt,name=exec_id,json=execId,proto3" json:"exec_id,omitempty"` -} - -func (x *WaitRequest) Reset() { - *x = WaitRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[25] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WaitRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WaitRequest) ProtoMessage() {} - -func (x *WaitRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[25] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WaitRequest.ProtoReflect.Descriptor instead. -func (*WaitRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{25} -} - -func (x *WaitRequest) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *WaitRequest) GetExecID() string { - if x != nil { - return x.ExecID - } - return "" -} - -type WaitResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ExitStatus uint32 `protobuf:"varint,1,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` - ExitedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=exited_at,json=exitedAt,proto3" json:"exited_at,omitempty"` -} - -func (x *WaitResponse) Reset() { - *x = WaitResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[26] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *WaitResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*WaitResponse) ProtoMessage() {} - -func (x *WaitResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[26] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use WaitResponse.ProtoReflect.Descriptor instead. -func (*WaitResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP(), []int{26} -} - -func (x *WaitResponse) GetExitStatus() uint32 { - if x != nil { - return x.ExitStatus - } - return 0 -} - -func (x *WaitResponse) GetExitedAt() *timestamppb.Timestamp { - if x != nil { - return x.ExitedAt - } - return nil -} - -var File_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDesc = []byte{ - 0x0a, 0x42, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, - 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2f, 0x76, 0x31, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, - 0x76, 0x31, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, - 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x36, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6d, - 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3b, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, - 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xda, 0x02, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x2f, 0x0a, 0x06, 0x72, 0x6f, 0x6f, 0x74, 0x66, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x72, 0x6f, 0x6f, 0x74, 0x66, 0x73, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, - 0x61, 0x6c, 0x12, 0x3c, 0x0a, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x6f, 0x72, 0x52, 0x0a, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x12, 0x2e, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x50, - 0x61, 0x74, 0x68, 0x22, 0x49, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, - 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x10, 0x0a, 0x03, - 0x70, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x4a, - 0x0a, 0x0c, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, - 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x22, 0x21, 0x0a, 0x0d, 0x53, 0x74, - 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x70, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x22, 0x36, 0x0a, - 0x11, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x8c, 0x01, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, - 0x69, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0a, 0x65, 0x78, 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x37, 0x0a, 0x09, 0x65, - 0x78, 0x69, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x22, 0x52, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, - 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x22, 0x48, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, - 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, - 0x49, 0x64, 0x22, 0x45, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x36, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x76, 0x31, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x52, 0x07, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x22, 0x2a, 0x0a, 0x10, 0x4c, 0x69, 0x73, - 0x74, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, - 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x22, 0x47, 0x0a, 0x11, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, 0x73, - 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x05, 0x74, 0x61, - 0x73, 0x6b, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x05, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x22, 0x73, - 0x0a, 0x0b, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x69, 0x67, - 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x69, 0x67, 0x6e, 0x61, - 0x6c, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x03, - 0x61, 0x6c, 0x6c, 0x22, 0xdc, 0x01, 0x0a, 0x12, 0x45, 0x78, 0x65, 0x63, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, - 0x64, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, - 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, - 0x65, 0x72, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x12, - 0x28, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x41, 0x6e, 0x79, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, - 0x63, 0x5f, 0x69, 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, - 0x49, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x45, 0x78, 0x65, 0x63, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x7c, 0x0a, 0x10, 0x52, 0x65, 0x73, - 0x69, 0x7a, 0x65, 0x50, 0x74, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x12, 0x17, 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x77, 0x69, 0x64, 0x74, 0x68, 0x12, - 0x16, 0x0a, 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x06, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x22, 0x62, 0x0a, 0x0e, 0x43, 0x6c, 0x6f, 0x73, 0x65, - 0x49, 0x4f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, 0x0a, 0x07, - 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x65, - 0x78, 0x65, 0x63, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x22, 0x35, 0x0a, 0x10, 0x50, - 0x61, 0x75, 0x73, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x64, 0x22, 0x36, 0x0a, 0x11, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, 0x61, 0x73, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x22, 0x34, 0x0a, 0x0f, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x69, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, - 0x22, 0x52, 0x0a, 0x10, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x69, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x22, 0x97, 0x01, 0x0a, 0x15, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, - 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x2b, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x63, 0x68, 0x65, 0x63, - 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x70, 0x61, - 0x72, 0x65, 0x6e, 0x74, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x2e, - 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0x58, - 0x0a, 0x16, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x61, 0x73, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, - 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x52, 0x0b, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x73, 0x22, 0x8e, 0x02, 0x0a, 0x11, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, - 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, - 0x64, 0x12, 0x32, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x62, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x40, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x41, 0x6e, 0x6e, 0x6f, - 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x2a, 0x0a, 0x0e, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x66, - 0x69, 0x6c, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x73, 0x22, 0x45, 0x0a, 0x0f, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x32, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x22, 0x49, 0x0a, 0x0b, - 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x17, - 0x0a, 0x07, 0x65, 0x78, 0x65, 0x63, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x65, 0x78, 0x65, 0x63, 0x49, 0x64, 0x22, 0x68, 0x0a, 0x0c, 0x57, 0x61, 0x69, 0x74, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x69, 0x74, 0x5f, - 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x78, - 0x69, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, - 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x41, - 0x74, 0x32, 0xdc, 0x0c, 0x0a, 0x05, 0x54, 0x61, 0x73, 0x6b, 0x73, 0x12, 0x6b, 0x0a, 0x06, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, - 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, - 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x74, 0x61, - 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x67, 0x0a, 0x06, 0x44, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x12, 0x71, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x12, 0x32, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, - 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x28, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, - 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x67, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, - 0x73, 0x6b, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, - 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x54, 0x61, - 0x73, 0x6b, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x04, 0x4b, - 0x69, 0x6c, 0x6c, 0x12, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, - 0x76, 0x31, 0x2e, 0x4b, 0x69, 0x6c, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x50, 0x0a, 0x04, 0x45, 0x78, 0x65, 0x63, 0x12, 0x30, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, - 0x65, 0x63, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x53, 0x0a, 0x09, 0x52, 0x65, 0x73, 0x69, - 0x7a, 0x65, 0x50, 0x74, 0x79, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, - 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x50, 0x74, 0x79, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4f, 0x0a, - 0x07, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x49, 0x4f, 0x12, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, - 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x49, 0x4f, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4f, - 0x0a, 0x05, 0x50, 0x61, 0x75, 0x73, 0x65, 0x12, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, - 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x61, 0x75, 0x73, 0x65, 0x54, 0x61, 0x73, 0x6b, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x51, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, - 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6d, 0x65, 0x54, - 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x69, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x50, 0x69, 0x64, 0x73, 0x12, 0x2d, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, - 0x73, 0x74, 0x50, 0x69, 0x64, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, - 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x50, 0x69, 0x64, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, - 0x0a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x33, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x68, 0x65, 0x63, 0x6b, - 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x34, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x12, 0x2f, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, - 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x54, 0x61, 0x73, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x66, 0x0a, 0x07, 0x4d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x12, 0x2c, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x2d, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, - 0x31, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x5d, 0x0a, 0x04, 0x57, 0x61, 0x69, 0x74, 0x12, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, - 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2a, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x74, 0x61, 0x73, 0x6b, 0x73, - 0x2e, 0x76, 0x31, 0x2e, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, - 0x73, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x61, 0x73, 0x6b, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescData = file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes = make([]protoimpl.MessageInfo, 28) -var file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_goTypes = []interface{}{ - (*CreateTaskRequest)(nil), // 0: containerd.services.tasks.v1.CreateTaskRequest - (*CreateTaskResponse)(nil), // 1: containerd.services.tasks.v1.CreateTaskResponse - (*StartRequest)(nil), // 2: containerd.services.tasks.v1.StartRequest - (*StartResponse)(nil), // 3: containerd.services.tasks.v1.StartResponse - (*DeleteTaskRequest)(nil), // 4: containerd.services.tasks.v1.DeleteTaskRequest - (*DeleteResponse)(nil), // 5: containerd.services.tasks.v1.DeleteResponse - (*DeleteProcessRequest)(nil), // 6: containerd.services.tasks.v1.DeleteProcessRequest - (*GetRequest)(nil), // 7: containerd.services.tasks.v1.GetRequest - (*GetResponse)(nil), // 8: containerd.services.tasks.v1.GetResponse - (*ListTasksRequest)(nil), // 9: containerd.services.tasks.v1.ListTasksRequest - (*ListTasksResponse)(nil), // 10: containerd.services.tasks.v1.ListTasksResponse - (*KillRequest)(nil), // 11: containerd.services.tasks.v1.KillRequest - (*ExecProcessRequest)(nil), // 12: containerd.services.tasks.v1.ExecProcessRequest - (*ExecProcessResponse)(nil), // 13: containerd.services.tasks.v1.ExecProcessResponse - (*ResizePtyRequest)(nil), // 14: containerd.services.tasks.v1.ResizePtyRequest - (*CloseIORequest)(nil), // 15: containerd.services.tasks.v1.CloseIORequest - (*PauseTaskRequest)(nil), // 16: containerd.services.tasks.v1.PauseTaskRequest - (*ResumeTaskRequest)(nil), // 17: containerd.services.tasks.v1.ResumeTaskRequest - (*ListPidsRequest)(nil), // 18: containerd.services.tasks.v1.ListPidsRequest - (*ListPidsResponse)(nil), // 19: containerd.services.tasks.v1.ListPidsResponse - (*CheckpointTaskRequest)(nil), // 20: containerd.services.tasks.v1.CheckpointTaskRequest - (*CheckpointTaskResponse)(nil), // 21: containerd.services.tasks.v1.CheckpointTaskResponse - (*UpdateTaskRequest)(nil), // 22: containerd.services.tasks.v1.UpdateTaskRequest - (*MetricsRequest)(nil), // 23: containerd.services.tasks.v1.MetricsRequest - (*MetricsResponse)(nil), // 24: containerd.services.tasks.v1.MetricsResponse - (*WaitRequest)(nil), // 25: containerd.services.tasks.v1.WaitRequest - (*WaitResponse)(nil), // 26: containerd.services.tasks.v1.WaitResponse - nil, // 27: containerd.services.tasks.v1.UpdateTaskRequest.AnnotationsEntry - (*types.Mount)(nil), // 28: containerd.types.Mount - (*types.Descriptor)(nil), // 29: containerd.types.Descriptor - (*anypb.Any)(nil), // 30: google.protobuf.Any - (*timestamppb.Timestamp)(nil), // 31: google.protobuf.Timestamp - (*task.Process)(nil), // 32: containerd.v1.types.Process - (*task.ProcessInfo)(nil), // 33: containerd.v1.types.ProcessInfo - (*types.Metric)(nil), // 34: containerd.types.Metric - (*emptypb.Empty)(nil), // 35: google.protobuf.Empty -} -var file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_depIdxs = []int32{ - 28, // 0: containerd.services.tasks.v1.CreateTaskRequest.rootfs:type_name -> containerd.types.Mount - 29, // 1: containerd.services.tasks.v1.CreateTaskRequest.checkpoint:type_name -> containerd.types.Descriptor - 30, // 2: containerd.services.tasks.v1.CreateTaskRequest.options:type_name -> google.protobuf.Any - 31, // 3: containerd.services.tasks.v1.DeleteResponse.exited_at:type_name -> google.protobuf.Timestamp - 32, // 4: containerd.services.tasks.v1.GetResponse.process:type_name -> containerd.v1.types.Process - 32, // 5: containerd.services.tasks.v1.ListTasksResponse.tasks:type_name -> containerd.v1.types.Process - 30, // 6: containerd.services.tasks.v1.ExecProcessRequest.spec:type_name -> google.protobuf.Any - 33, // 7: containerd.services.tasks.v1.ListPidsResponse.processes:type_name -> containerd.v1.types.ProcessInfo - 30, // 8: containerd.services.tasks.v1.CheckpointTaskRequest.options:type_name -> google.protobuf.Any - 29, // 9: containerd.services.tasks.v1.CheckpointTaskResponse.descriptors:type_name -> containerd.types.Descriptor - 30, // 10: containerd.services.tasks.v1.UpdateTaskRequest.resources:type_name -> google.protobuf.Any - 27, // 11: containerd.services.tasks.v1.UpdateTaskRequest.annotations:type_name -> containerd.services.tasks.v1.UpdateTaskRequest.AnnotationsEntry - 34, // 12: containerd.services.tasks.v1.MetricsResponse.metrics:type_name -> containerd.types.Metric - 31, // 13: containerd.services.tasks.v1.WaitResponse.exited_at:type_name -> google.protobuf.Timestamp - 0, // 14: containerd.services.tasks.v1.Tasks.Create:input_type -> containerd.services.tasks.v1.CreateTaskRequest - 2, // 15: containerd.services.tasks.v1.Tasks.Start:input_type -> containerd.services.tasks.v1.StartRequest - 4, // 16: containerd.services.tasks.v1.Tasks.Delete:input_type -> containerd.services.tasks.v1.DeleteTaskRequest - 6, // 17: containerd.services.tasks.v1.Tasks.DeleteProcess:input_type -> containerd.services.tasks.v1.DeleteProcessRequest - 7, // 18: containerd.services.tasks.v1.Tasks.Get:input_type -> containerd.services.tasks.v1.GetRequest - 9, // 19: containerd.services.tasks.v1.Tasks.List:input_type -> containerd.services.tasks.v1.ListTasksRequest - 11, // 20: containerd.services.tasks.v1.Tasks.Kill:input_type -> containerd.services.tasks.v1.KillRequest - 12, // 21: containerd.services.tasks.v1.Tasks.Exec:input_type -> containerd.services.tasks.v1.ExecProcessRequest - 14, // 22: containerd.services.tasks.v1.Tasks.ResizePty:input_type -> containerd.services.tasks.v1.ResizePtyRequest - 15, // 23: containerd.services.tasks.v1.Tasks.CloseIO:input_type -> containerd.services.tasks.v1.CloseIORequest - 16, // 24: containerd.services.tasks.v1.Tasks.Pause:input_type -> containerd.services.tasks.v1.PauseTaskRequest - 17, // 25: containerd.services.tasks.v1.Tasks.Resume:input_type -> containerd.services.tasks.v1.ResumeTaskRequest - 18, // 26: containerd.services.tasks.v1.Tasks.ListPids:input_type -> containerd.services.tasks.v1.ListPidsRequest - 20, // 27: containerd.services.tasks.v1.Tasks.Checkpoint:input_type -> containerd.services.tasks.v1.CheckpointTaskRequest - 22, // 28: containerd.services.tasks.v1.Tasks.Update:input_type -> containerd.services.tasks.v1.UpdateTaskRequest - 23, // 29: containerd.services.tasks.v1.Tasks.Metrics:input_type -> containerd.services.tasks.v1.MetricsRequest - 25, // 30: containerd.services.tasks.v1.Tasks.Wait:input_type -> containerd.services.tasks.v1.WaitRequest - 1, // 31: containerd.services.tasks.v1.Tasks.Create:output_type -> containerd.services.tasks.v1.CreateTaskResponse - 3, // 32: containerd.services.tasks.v1.Tasks.Start:output_type -> containerd.services.tasks.v1.StartResponse - 5, // 33: containerd.services.tasks.v1.Tasks.Delete:output_type -> containerd.services.tasks.v1.DeleteResponse - 5, // 34: containerd.services.tasks.v1.Tasks.DeleteProcess:output_type -> containerd.services.tasks.v1.DeleteResponse - 8, // 35: containerd.services.tasks.v1.Tasks.Get:output_type -> containerd.services.tasks.v1.GetResponse - 10, // 36: containerd.services.tasks.v1.Tasks.List:output_type -> containerd.services.tasks.v1.ListTasksResponse - 35, // 37: containerd.services.tasks.v1.Tasks.Kill:output_type -> google.protobuf.Empty - 35, // 38: containerd.services.tasks.v1.Tasks.Exec:output_type -> google.protobuf.Empty - 35, // 39: containerd.services.tasks.v1.Tasks.ResizePty:output_type -> google.protobuf.Empty - 35, // 40: containerd.services.tasks.v1.Tasks.CloseIO:output_type -> google.protobuf.Empty - 35, // 41: containerd.services.tasks.v1.Tasks.Pause:output_type -> google.protobuf.Empty - 35, // 42: containerd.services.tasks.v1.Tasks.Resume:output_type -> google.protobuf.Empty - 19, // 43: containerd.services.tasks.v1.Tasks.ListPids:output_type -> containerd.services.tasks.v1.ListPidsResponse - 21, // 44: containerd.services.tasks.v1.Tasks.Checkpoint:output_type -> containerd.services.tasks.v1.CheckpointTaskResponse - 35, // 45: containerd.services.tasks.v1.Tasks.Update:output_type -> google.protobuf.Empty - 24, // 46: containerd.services.tasks.v1.Tasks.Metrics:output_type -> containerd.services.tasks.v1.MetricsResponse - 26, // 47: containerd.services.tasks.v1.Tasks.Wait:output_type -> containerd.services.tasks.v1.WaitResponse - 31, // [31:48] is the sub-list for method output_type - 14, // [14:31] is the sub-list for method input_type - 14, // [14:14] is the sub-list for extension type_name - 14, // [14:14] is the sub-list for extension extendee - 0, // [0:14] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_init() } -func file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_init() { - if File_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateTaskRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CreateTaskResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StartResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteTaskRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DeleteProcessRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*GetResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListTasksRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListTasksResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KillRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecProcessRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ExecProcessResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResizePtyRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CloseIORequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*PauseTaskRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResumeTaskRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPidsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListPidsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckpointTaskRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CheckpointTaskResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UpdateTaskRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetricsRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MetricsResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WaitRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*WaitResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDesc, - NumEnums: 0, - NumMessages: 28, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto = out.File - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_rawDesc = nil - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_goTypes = nil - file_github_com_containerd_containerd_api_services_tasks_v1_tasks_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto deleted file mode 100644 index 8ddd31926..000000000 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks.proto +++ /dev/null @@ -1,227 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.services.tasks.v1; - -import "google/protobuf/empty.proto"; -import "google/protobuf/any.proto"; -import "github.com/containerd/containerd/api/types/mount.proto"; -import "github.com/containerd/containerd/api/types/metrics.proto"; -import "github.com/containerd/containerd/api/types/descriptor.proto"; -import "github.com/containerd/containerd/api/types/task/task.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/containerd/containerd/api/services/tasks/v1;tasks"; - -service Tasks { - // Create a task. - rpc Create(CreateTaskRequest) returns (CreateTaskResponse); - - // Start a process. - rpc Start(StartRequest) returns (StartResponse); - - // Delete a task and on disk state. - rpc Delete(DeleteTaskRequest) returns (DeleteResponse); - - rpc DeleteProcess(DeleteProcessRequest) returns (DeleteResponse); - - rpc Get(GetRequest) returns (GetResponse); - - rpc List(ListTasksRequest) returns (ListTasksResponse); - - // Kill a task or process. - rpc Kill(KillRequest) returns (google.protobuf.Empty); - - rpc Exec(ExecProcessRequest) returns (google.protobuf.Empty); - - rpc ResizePty(ResizePtyRequest) returns (google.protobuf.Empty); - - rpc CloseIO(CloseIORequest) returns (google.protobuf.Empty); - - rpc Pause(PauseTaskRequest) returns (google.protobuf.Empty); - - rpc Resume(ResumeTaskRequest) returns (google.protobuf.Empty); - - rpc ListPids(ListPidsRequest) returns (ListPidsResponse); - - rpc Checkpoint(CheckpointTaskRequest) returns (CheckpointTaskResponse); - - rpc Update(UpdateTaskRequest) returns (google.protobuf.Empty); - - rpc Metrics(MetricsRequest) returns (MetricsResponse); - - rpc Wait(WaitRequest) returns (WaitResponse); -} - -message CreateTaskRequest { - string container_id = 1; - - // RootFS provides the pre-chroot mounts to perform in the shim before - // executing the container task. - // - // These are for mounts that cannot be performed in the user namespace. - // Typically, these mounts should be resolved from snapshots specified on - // the container object. - repeated containerd.types.Mount rootfs = 3; - - string stdin = 4; - string stdout = 5; - string stderr = 6; - bool terminal = 7; - - containerd.types.Descriptor checkpoint = 8; - - google.protobuf.Any options = 9; - - string runtime_path = 10; -} - -message CreateTaskResponse { - string container_id = 1; - uint32 pid = 2; -} - -message StartRequest { - string container_id = 1; - string exec_id = 2; -} - -message StartResponse { - uint32 pid = 1; -} - -message DeleteTaskRequest { - string container_id = 1; -} - -message DeleteResponse { - string id = 1; - uint32 pid = 2; - uint32 exit_status = 3; - google.protobuf.Timestamp exited_at = 4; -} - -message DeleteProcessRequest { - string container_id = 1; - string exec_id = 2; -} - -message GetRequest { - string container_id = 1; - string exec_id = 2; -} - -message GetResponse { - containerd.v1.types.Process process = 1; -} - -message ListTasksRequest { - string filter = 1; -} - -message ListTasksResponse { - repeated containerd.v1.types.Process tasks = 1; -} - -message KillRequest { - string container_id = 1; - string exec_id = 2; - uint32 signal = 3; - bool all = 4; -} - -message ExecProcessRequest { - string container_id = 1; - string stdin = 2; - string stdout = 3; - string stderr = 4; - bool terminal = 5; - // Spec for starting a process in the target container. - // - // For runc, this is a process spec, for example. - google.protobuf.Any spec = 6; - // id of the exec process - string exec_id = 7; -} - -message ExecProcessResponse { -} - -message ResizePtyRequest { - string container_id = 1; - string exec_id = 2; - uint32 width = 3; - uint32 height = 4; -} - -message CloseIORequest { - string container_id = 1; - string exec_id = 2; - bool stdin = 3; -} - -message PauseTaskRequest { - string container_id = 1; -} - -message ResumeTaskRequest { - string container_id = 1; -} - -message ListPidsRequest { - string container_id = 1; -} - -message ListPidsResponse { - // Processes includes the process ID and additional process information - repeated containerd.v1.types.ProcessInfo processes = 1; -} - -message CheckpointTaskRequest { - string container_id = 1; - string parent_checkpoint = 2; - google.protobuf.Any options = 3; -} - -message CheckpointTaskResponse { - repeated containerd.types.Descriptor descriptors = 1; -} - -message UpdateTaskRequest { - string container_id = 1; - google.protobuf.Any resources = 2; - map annotations = 3; -} - -message MetricsRequest { - repeated string filters = 1; -} - -message MetricsResponse { - repeated types.Metric metrics = 1; -} - -message WaitRequest { - string container_id = 1; - string exec_id = 2; -} - -message WaitResponse { - uint32 exit_status = 1; - google.protobuf.Timestamp exited_at = 2; -} diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_grpc.pb.go b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_grpc.pb.go deleted file mode 100644 index 1bc23522a..000000000 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_grpc.pb.go +++ /dev/null @@ -1,692 +0,0 @@ -//go:build !no_grpc - -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.20.1 -// source: github.com/containerd/containerd/api/services/tasks/v1/tasks.proto - -package tasks - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// TasksClient is the client API for Tasks service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type TasksClient interface { - // Create a task. - Create(ctx context.Context, in *CreateTaskRequest, opts ...grpc.CallOption) (*CreateTaskResponse, error) - // Start a process. - Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) - // Delete a task and on disk state. - Delete(ctx context.Context, in *DeleteTaskRequest, opts ...grpc.CallOption) (*DeleteResponse, error) - DeleteProcess(ctx context.Context, in *DeleteProcessRequest, opts ...grpc.CallOption) (*DeleteResponse, error) - Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) - List(ctx context.Context, in *ListTasksRequest, opts ...grpc.CallOption) (*ListTasksResponse, error) - // Kill a task or process. - Kill(ctx context.Context, in *KillRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - Exec(ctx context.Context, in *ExecProcessRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - ResizePty(ctx context.Context, in *ResizePtyRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - CloseIO(ctx context.Context, in *CloseIORequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - Pause(ctx context.Context, in *PauseTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - Resume(ctx context.Context, in *ResumeTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - ListPids(ctx context.Context, in *ListPidsRequest, opts ...grpc.CallOption) (*ListPidsResponse, error) - Checkpoint(ctx context.Context, in *CheckpointTaskRequest, opts ...grpc.CallOption) (*CheckpointTaskResponse, error) - Update(ctx context.Context, in *UpdateTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) - Metrics(ctx context.Context, in *MetricsRequest, opts ...grpc.CallOption) (*MetricsResponse, error) - Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (*WaitResponse, error) -} - -type tasksClient struct { - cc grpc.ClientConnInterface -} - -func NewTasksClient(cc grpc.ClientConnInterface) TasksClient { - return &tasksClient{cc} -} - -func (c *tasksClient) Create(ctx context.Context, in *CreateTaskRequest, opts ...grpc.CallOption) (*CreateTaskResponse, error) { - out := new(CreateTaskResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Create", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Start(ctx context.Context, in *StartRequest, opts ...grpc.CallOption) (*StartResponse, error) { - out := new(StartResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Start", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Delete(ctx context.Context, in *DeleteTaskRequest, opts ...grpc.CallOption) (*DeleteResponse, error) { - out := new(DeleteResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Delete", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) DeleteProcess(ctx context.Context, in *DeleteProcessRequest, opts ...grpc.CallOption) (*DeleteResponse, error) { - out := new(DeleteResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/DeleteProcess", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Get(ctx context.Context, in *GetRequest, opts ...grpc.CallOption) (*GetResponse, error) { - out := new(GetResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Get", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) List(ctx context.Context, in *ListTasksRequest, opts ...grpc.CallOption) (*ListTasksResponse, error) { - out := new(ListTasksResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/List", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Kill(ctx context.Context, in *KillRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Kill", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Exec(ctx context.Context, in *ExecProcessRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Exec", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) ResizePty(ctx context.Context, in *ResizePtyRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/ResizePty", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) CloseIO(ctx context.Context, in *CloseIORequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/CloseIO", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Pause(ctx context.Context, in *PauseTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Pause", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Resume(ctx context.Context, in *ResumeTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Resume", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) ListPids(ctx context.Context, in *ListPidsRequest, opts ...grpc.CallOption) (*ListPidsResponse, error) { - out := new(ListPidsResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/ListPids", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Checkpoint(ctx context.Context, in *CheckpointTaskRequest, opts ...grpc.CallOption) (*CheckpointTaskResponse, error) { - out := new(CheckpointTaskResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Checkpoint", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Update(ctx context.Context, in *UpdateTaskRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Update", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Metrics(ctx context.Context, in *MetricsRequest, opts ...grpc.CallOption) (*MetricsResponse, error) { - out := new(MetricsResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Metrics", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tasksClient) Wait(ctx context.Context, in *WaitRequest, opts ...grpc.CallOption) (*WaitResponse, error) { - out := new(WaitResponse) - err := c.cc.Invoke(ctx, "/containerd.services.tasks.v1.Tasks/Wait", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// TasksServer is the server API for Tasks service. -// All implementations must embed UnimplementedTasksServer -// for forward compatibility -type TasksServer interface { - // Create a task. - Create(context.Context, *CreateTaskRequest) (*CreateTaskResponse, error) - // Start a process. - Start(context.Context, *StartRequest) (*StartResponse, error) - // Delete a task and on disk state. - Delete(context.Context, *DeleteTaskRequest) (*DeleteResponse, error) - DeleteProcess(context.Context, *DeleteProcessRequest) (*DeleteResponse, error) - Get(context.Context, *GetRequest) (*GetResponse, error) - List(context.Context, *ListTasksRequest) (*ListTasksResponse, error) - // Kill a task or process. - Kill(context.Context, *KillRequest) (*emptypb.Empty, error) - Exec(context.Context, *ExecProcessRequest) (*emptypb.Empty, error) - ResizePty(context.Context, *ResizePtyRequest) (*emptypb.Empty, error) - CloseIO(context.Context, *CloseIORequest) (*emptypb.Empty, error) - Pause(context.Context, *PauseTaskRequest) (*emptypb.Empty, error) - Resume(context.Context, *ResumeTaskRequest) (*emptypb.Empty, error) - ListPids(context.Context, *ListPidsRequest) (*ListPidsResponse, error) - Checkpoint(context.Context, *CheckpointTaskRequest) (*CheckpointTaskResponse, error) - Update(context.Context, *UpdateTaskRequest) (*emptypb.Empty, error) - Metrics(context.Context, *MetricsRequest) (*MetricsResponse, error) - Wait(context.Context, *WaitRequest) (*WaitResponse, error) - mustEmbedUnimplementedTasksServer() -} - -// UnimplementedTasksServer must be embedded to have forward compatible implementations. -type UnimplementedTasksServer struct { -} - -func (UnimplementedTasksServer) Create(context.Context, *CreateTaskRequest) (*CreateTaskResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Create not implemented") -} -func (UnimplementedTasksServer) Start(context.Context, *StartRequest) (*StartResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Start not implemented") -} -func (UnimplementedTasksServer) Delete(context.Context, *DeleteTaskRequest) (*DeleteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") -} -func (UnimplementedTasksServer) DeleteProcess(context.Context, *DeleteProcessRequest) (*DeleteResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method DeleteProcess not implemented") -} -func (UnimplementedTasksServer) Get(context.Context, *GetRequest) (*GetResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Get not implemented") -} -func (UnimplementedTasksServer) List(context.Context, *ListTasksRequest) (*ListTasksResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method List not implemented") -} -func (UnimplementedTasksServer) Kill(context.Context, *KillRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Kill not implemented") -} -func (UnimplementedTasksServer) Exec(context.Context, *ExecProcessRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Exec not implemented") -} -func (UnimplementedTasksServer) ResizePty(context.Context, *ResizePtyRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method ResizePty not implemented") -} -func (UnimplementedTasksServer) CloseIO(context.Context, *CloseIORequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method CloseIO not implemented") -} -func (UnimplementedTasksServer) Pause(context.Context, *PauseTaskRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Pause not implemented") -} -func (UnimplementedTasksServer) Resume(context.Context, *ResumeTaskRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Resume not implemented") -} -func (UnimplementedTasksServer) ListPids(context.Context, *ListPidsRequest) (*ListPidsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListPids not implemented") -} -func (UnimplementedTasksServer) Checkpoint(context.Context, *CheckpointTaskRequest) (*CheckpointTaskResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Checkpoint not implemented") -} -func (UnimplementedTasksServer) Update(context.Context, *UpdateTaskRequest) (*emptypb.Empty, error) { - return nil, status.Errorf(codes.Unimplemented, "method Update not implemented") -} -func (UnimplementedTasksServer) Metrics(context.Context, *MetricsRequest) (*MetricsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Metrics not implemented") -} -func (UnimplementedTasksServer) Wait(context.Context, *WaitRequest) (*WaitResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Wait not implemented") -} -func (UnimplementedTasksServer) mustEmbedUnimplementedTasksServer() {} - -// UnsafeTasksServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to TasksServer will -// result in compilation errors. -type UnsafeTasksServer interface { - mustEmbedUnimplementedTasksServer() -} - -func RegisterTasksServer(s grpc.ServiceRegistrar, srv TasksServer) { - s.RegisterService(&Tasks_ServiceDesc, srv) -} - -func _Tasks_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CreateTaskRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Create(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Create", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Create(ctx, req.(*CreateTaskRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Start_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(StartRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Start(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Start", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Start(ctx, req.(*StartRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteTaskRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Delete(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Delete", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Delete(ctx, req.(*DeleteTaskRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_DeleteProcess_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteProcessRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).DeleteProcess(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/DeleteProcess", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).DeleteProcess(ctx, req.(*DeleteProcessRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(GetRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Get(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Get", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Get(ctx, req.(*GetRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListTasksRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).List(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/List", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).List(ctx, req.(*ListTasksRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Kill_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(KillRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Kill(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Kill", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Kill(ctx, req.(*KillRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Exec_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ExecProcessRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Exec(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Exec", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Exec(ctx, req.(*ExecProcessRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_ResizePty_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResizePtyRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).ResizePty(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/ResizePty", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).ResizePty(ctx, req.(*ResizePtyRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_CloseIO_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CloseIORequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).CloseIO(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/CloseIO", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).CloseIO(ctx, req.(*CloseIORequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Pause_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(PauseTaskRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Pause(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Pause", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Pause(ctx, req.(*PauseTaskRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Resume_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ResumeTaskRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Resume(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Resume", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Resume(ctx, req.(*ResumeTaskRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_ListPids_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListPidsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).ListPids(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/ListPids", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).ListPids(ctx, req.(*ListPidsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Checkpoint_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CheckpointTaskRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Checkpoint(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Checkpoint", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Checkpoint(ctx, req.(*CheckpointTaskRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(UpdateTaskRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Update(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Update", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Update(ctx, req.(*UpdateTaskRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Metrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(MetricsRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Metrics(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Metrics", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Metrics(ctx, req.(*MetricsRequest)) - } - return interceptor(ctx, in, info, handler) -} - -func _Tasks_Wait_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(WaitRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TasksServer).Wait(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.tasks.v1.Tasks/Wait", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TasksServer).Wait(ctx, req.(*WaitRequest)) - } - return interceptor(ctx, in, info, handler) -} - -// Tasks_ServiceDesc is the grpc.ServiceDesc for Tasks service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Tasks_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "containerd.services.tasks.v1.Tasks", - HandlerType: (*TasksServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Create", - Handler: _Tasks_Create_Handler, - }, - { - MethodName: "Start", - Handler: _Tasks_Start_Handler, - }, - { - MethodName: "Delete", - Handler: _Tasks_Delete_Handler, - }, - { - MethodName: "DeleteProcess", - Handler: _Tasks_DeleteProcess_Handler, - }, - { - MethodName: "Get", - Handler: _Tasks_Get_Handler, - }, - { - MethodName: "List", - Handler: _Tasks_List_Handler, - }, - { - MethodName: "Kill", - Handler: _Tasks_Kill_Handler, - }, - { - MethodName: "Exec", - Handler: _Tasks_Exec_Handler, - }, - { - MethodName: "ResizePty", - Handler: _Tasks_ResizePty_Handler, - }, - { - MethodName: "CloseIO", - Handler: _Tasks_CloseIO_Handler, - }, - { - MethodName: "Pause", - Handler: _Tasks_Pause_Handler, - }, - { - MethodName: "Resume", - Handler: _Tasks_Resume_Handler, - }, - { - MethodName: "ListPids", - Handler: _Tasks_ListPids_Handler, - }, - { - MethodName: "Checkpoint", - Handler: _Tasks_Checkpoint_Handler, - }, - { - MethodName: "Update", - Handler: _Tasks_Update_Handler, - }, - { - MethodName: "Metrics", - Handler: _Tasks_Metrics_Handler, - }, - { - MethodName: "Wait", - Handler: _Tasks_Wait_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "github.com/containerd/containerd/api/services/tasks/v1/tasks.proto", -} diff --git a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_ttrpc.pb.go b/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_ttrpc.pb.go deleted file mode 100644 index 859eec58e..000000000 --- a/vendor/github.com/containerd/containerd/api/services/tasks/v1/tasks_ttrpc.pb.go +++ /dev/null @@ -1,301 +0,0 @@ -// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT. -// source: github.com/containerd/containerd/api/services/tasks/v1/tasks.proto -package tasks - -import ( - context "context" - ttrpc "github.com/containerd/ttrpc" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -type TTRPCTasksService interface { - Create(context.Context, *CreateTaskRequest) (*CreateTaskResponse, error) - Start(context.Context, *StartRequest) (*StartResponse, error) - Delete(context.Context, *DeleteTaskRequest) (*DeleteResponse, error) - DeleteProcess(context.Context, *DeleteProcessRequest) (*DeleteResponse, error) - Get(context.Context, *GetRequest) (*GetResponse, error) - List(context.Context, *ListTasksRequest) (*ListTasksResponse, error) - Kill(context.Context, *KillRequest) (*emptypb.Empty, error) - Exec(context.Context, *ExecProcessRequest) (*emptypb.Empty, error) - ResizePty(context.Context, *ResizePtyRequest) (*emptypb.Empty, error) - CloseIO(context.Context, *CloseIORequest) (*emptypb.Empty, error) - Pause(context.Context, *PauseTaskRequest) (*emptypb.Empty, error) - Resume(context.Context, *ResumeTaskRequest) (*emptypb.Empty, error) - ListPids(context.Context, *ListPidsRequest) (*ListPidsResponse, error) - Checkpoint(context.Context, *CheckpointTaskRequest) (*CheckpointTaskResponse, error) - Update(context.Context, *UpdateTaskRequest) (*emptypb.Empty, error) - Metrics(context.Context, *MetricsRequest) (*MetricsResponse, error) - Wait(context.Context, *WaitRequest) (*WaitResponse, error) -} - -func RegisterTTRPCTasksService(srv *ttrpc.Server, svc TTRPCTasksService) { - srv.RegisterService("containerd.services.tasks.v1.Tasks", &ttrpc.ServiceDesc{ - Methods: map[string]ttrpc.Method{ - "Create": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req CreateTaskRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Create(ctx, &req) - }, - "Start": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req StartRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Start(ctx, &req) - }, - "Delete": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req DeleteTaskRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Delete(ctx, &req) - }, - "DeleteProcess": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req DeleteProcessRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.DeleteProcess(ctx, &req) - }, - "Get": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req GetRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Get(ctx, &req) - }, - "List": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req ListTasksRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.List(ctx, &req) - }, - "Kill": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req KillRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Kill(ctx, &req) - }, - "Exec": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req ExecProcessRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Exec(ctx, &req) - }, - "ResizePty": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req ResizePtyRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.ResizePty(ctx, &req) - }, - "CloseIO": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req CloseIORequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.CloseIO(ctx, &req) - }, - "Pause": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req PauseTaskRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Pause(ctx, &req) - }, - "Resume": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req ResumeTaskRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Resume(ctx, &req) - }, - "ListPids": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req ListPidsRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.ListPids(ctx, &req) - }, - "Checkpoint": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req CheckpointTaskRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Checkpoint(ctx, &req) - }, - "Update": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req UpdateTaskRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Update(ctx, &req) - }, - "Metrics": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req MetricsRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Metrics(ctx, &req) - }, - "Wait": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req WaitRequest - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Wait(ctx, &req) - }, - }, - }) -} - -type ttrpctasksClient struct { - client *ttrpc.Client -} - -func NewTTRPCTasksClient(client *ttrpc.Client) TTRPCTasksService { - return &ttrpctasksClient{ - client: client, - } -} - -func (c *ttrpctasksClient) Create(ctx context.Context, req *CreateTaskRequest) (*CreateTaskResponse, error) { - var resp CreateTaskResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Create", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Start(ctx context.Context, req *StartRequest) (*StartResponse, error) { - var resp StartResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Start", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Delete(ctx context.Context, req *DeleteTaskRequest) (*DeleteResponse, error) { - var resp DeleteResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Delete", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) DeleteProcess(ctx context.Context, req *DeleteProcessRequest) (*DeleteResponse, error) { - var resp DeleteResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "DeleteProcess", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Get(ctx context.Context, req *GetRequest) (*GetResponse, error) { - var resp GetResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Get", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) List(ctx context.Context, req *ListTasksRequest) (*ListTasksResponse, error) { - var resp ListTasksResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "List", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Kill(ctx context.Context, req *KillRequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Kill", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Exec(ctx context.Context, req *ExecProcessRequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Exec", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) ResizePty(ctx context.Context, req *ResizePtyRequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "ResizePty", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) CloseIO(ctx context.Context, req *CloseIORequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "CloseIO", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Pause(ctx context.Context, req *PauseTaskRequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Pause", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Resume(ctx context.Context, req *ResumeTaskRequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Resume", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) ListPids(ctx context.Context, req *ListPidsRequest) (*ListPidsResponse, error) { - var resp ListPidsResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "ListPids", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Checkpoint(ctx context.Context, req *CheckpointTaskRequest) (*CheckpointTaskResponse, error) { - var resp CheckpointTaskResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Checkpoint", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Update(ctx context.Context, req *UpdateTaskRequest) (*emptypb.Empty, error) { - var resp emptypb.Empty - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Update", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Metrics(ctx context.Context, req *MetricsRequest) (*MetricsResponse, error) { - var resp MetricsResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Metrics", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} - -func (c *ttrpctasksClient) Wait(ctx context.Context, req *WaitRequest) (*WaitResponse, error) { - var resp WaitResponse - if err := c.client.Call(ctx, "containerd.services.tasks.v1.Tasks", "Wait", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} diff --git a/vendor/github.com/containerd/containerd/api/services/version/v1/doc.go b/vendor/github.com/containerd/containerd/api/services/version/v1/doc.go deleted file mode 100644 index c5c0b85dd..000000000 --- a/vendor/github.com/containerd/containerd/api/services/version/v1/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// Package version defines the version service. -package version diff --git a/vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go b/vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go deleted file mode 100644 index c087d3e26..000000000 --- a/vendor/github.com/containerd/containerd/api/services/version/v1/version.pb.go +++ /dev/null @@ -1,187 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/services/version/v1/version.proto - -package version - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type VersionResponse struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` -} - -func (x *VersionResponse) Reset() { - *x = VersionResponse{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_services_version_v1_version_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *VersionResponse) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*VersionResponse) ProtoMessage() {} - -func (x *VersionResponse) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_services_version_v1_version_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use VersionResponse.ProtoReflect.Descriptor instead. -func (*VersionResponse) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescGZIP(), []int{0} -} - -func (x *VersionResponse) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *VersionResponse) GetRevision() string { - if x != nil { - return x.Revision - } - return "" -} - -var File_github_com_containerd_containerd_api_services_version_v1_version_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDesc = []byte{ - 0x0a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, - 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x47, 0x0a, 0x0f, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x32, 0x5d, - 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x07, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x2f, 0x2e, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x73, 0x2e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x42, 0x5a, - 0x40, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescData = file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_services_version_v1_version_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_containerd_containerd_api_services_version_v1_version_proto_goTypes = []interface{}{ - (*VersionResponse)(nil), // 0: containerd.services.version.v1.VersionResponse - (*emptypb.Empty)(nil), // 1: google.protobuf.Empty -} -var file_github_com_containerd_containerd_api_services_version_v1_version_proto_depIdxs = []int32{ - 1, // 0: containerd.services.version.v1.Version.Version:input_type -> google.protobuf.Empty - 0, // 1: containerd.services.version.v1.Version.Version:output_type -> containerd.services.version.v1.VersionResponse - 1, // [1:2] is the sub-list for method output_type - 0, // [0:1] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_services_version_v1_version_proto_init() } -func file_github_com_containerd_containerd_api_services_version_v1_version_proto_init() { - if File_github_com_containerd_containerd_api_services_version_v1_version_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_services_version_v1_version_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VersionResponse); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_github_com_containerd_containerd_api_services_version_v1_version_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_services_version_v1_version_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_services_version_v1_version_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_services_version_v1_version_proto = out.File - file_github_com_containerd_containerd_api_services_version_v1_version_proto_rawDesc = nil - file_github_com_containerd_containerd_api_services_version_v1_version_proto_goTypes = nil - file_github_com_containerd_containerd_api_services_version_v1_version_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/services/version/v1/version.proto b/vendor/github.com/containerd/containerd/api/services/version/v1/version.proto deleted file mode 100644 index bd948ff34..000000000 --- a/vendor/github.com/containerd/containerd/api/services/version/v1/version.proto +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.services.version.v1; - -import "google/protobuf/empty.proto"; - -// TODO(stevvooe): Should version service actually be versioned? -option go_package = "github.com/containerd/containerd/api/services/version/v1;version"; - -service Version { - rpc Version(google.protobuf.Empty) returns (VersionResponse); -} - -message VersionResponse { - string version = 1; - string revision = 2; -} diff --git a/vendor/github.com/containerd/containerd/api/services/version/v1/version_grpc.pb.go b/vendor/github.com/containerd/containerd/api/services/version/v1/version_grpc.pb.go deleted file mode 100644 index e96eddefb..000000000 --- a/vendor/github.com/containerd/containerd/api/services/version/v1/version_grpc.pb.go +++ /dev/null @@ -1,108 +0,0 @@ -//go:build !no_grpc - -// Code generated by protoc-gen-go-grpc. DO NOT EDIT. -// versions: -// - protoc-gen-go-grpc v1.2.0 -// - protoc v3.20.1 -// source: github.com/containerd/containerd/api/services/version/v1/version.proto - -package version - -import ( - context "context" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 - -// VersionClient is the client API for Version service. -// -// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. -type VersionClient interface { - Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*VersionResponse, error) -} - -type versionClient struct { - cc grpc.ClientConnInterface -} - -func NewVersionClient(cc grpc.ClientConnInterface) VersionClient { - return &versionClient{cc} -} - -func (c *versionClient) Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*VersionResponse, error) { - out := new(VersionResponse) - err := c.cc.Invoke(ctx, "/containerd.services.version.v1.Version/Version", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// VersionServer is the server API for Version service. -// All implementations must embed UnimplementedVersionServer -// for forward compatibility -type VersionServer interface { - Version(context.Context, *emptypb.Empty) (*VersionResponse, error) - mustEmbedUnimplementedVersionServer() -} - -// UnimplementedVersionServer must be embedded to have forward compatible implementations. -type UnimplementedVersionServer struct { -} - -func (UnimplementedVersionServer) Version(context.Context, *emptypb.Empty) (*VersionResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method Version not implemented") -} -func (UnimplementedVersionServer) mustEmbedUnimplementedVersionServer() {} - -// UnsafeVersionServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to VersionServer will -// result in compilation errors. -type UnsafeVersionServer interface { - mustEmbedUnimplementedVersionServer() -} - -func RegisterVersionServer(s grpc.ServiceRegistrar, srv VersionServer) { - s.RegisterService(&Version_ServiceDesc, srv) -} - -func _Version_Version_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(emptypb.Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(VersionServer).Version(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/containerd.services.version.v1.Version/Version", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(VersionServer).Version(ctx, req.(*emptypb.Empty)) - } - return interceptor(ctx, in, info, handler) -} - -// Version_ServiceDesc is the grpc.ServiceDesc for Version service. -// It's only intended for direct use with grpc.RegisterService, -// and not to be introspected or modified (even as a copy) -var Version_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "containerd.services.version.v1.Version", - HandlerType: (*VersionServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "Version", - Handler: _Version_Version_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "github.com/containerd/containerd/api/services/version/v1/version.proto", -} diff --git a/vendor/github.com/containerd/containerd/api/services/version/v1/version_ttrpc.pb.go b/vendor/github.com/containerd/containerd/api/services/version/v1/version_ttrpc.pb.go deleted file mode 100644 index c284f14e7..000000000 --- a/vendor/github.com/containerd/containerd/api/services/version/v1/version_ttrpc.pb.go +++ /dev/null @@ -1,45 +0,0 @@ -// Code generated by protoc-gen-go-ttrpc. DO NOT EDIT. -// source: github.com/containerd/containerd/api/services/version/v1/version.proto -package version - -import ( - context "context" - ttrpc "github.com/containerd/ttrpc" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -type TTRPCVersionService interface { - Version(context.Context, *emptypb.Empty) (*VersionResponse, error) -} - -func RegisterTTRPCVersionService(srv *ttrpc.Server, svc TTRPCVersionService) { - srv.RegisterService("containerd.services.version.v1.Version", &ttrpc.ServiceDesc{ - Methods: map[string]ttrpc.Method{ - "Version": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - var req emptypb.Empty - if err := unmarshal(&req); err != nil { - return nil, err - } - return svc.Version(ctx, &req) - }, - }, - }) -} - -type ttrpcversionClient struct { - client *ttrpc.Client -} - -func NewTTRPCVersionClient(client *ttrpc.Client) TTRPCVersionService { - return &ttrpcversionClient{ - client: client, - } -} - -func (c *ttrpcversionClient) Version(ctx context.Context, req *emptypb.Empty) (*VersionResponse, error) { - var resp VersionResponse - if err := c.client.Call(ctx, "containerd.services.version.v1.Version", "Version", req, &resp); err != nil { - return nil, err - } - return &resp, nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go b/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go deleted file mode 100644 index f3db1c52d..000000000 --- a/vendor/github.com/containerd/containerd/api/types/descriptor.pb.go +++ /dev/null @@ -1,206 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/descriptor.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Descriptor describes a blob in a content store. -// -// This descriptor can be used to reference content from an -// oci descriptor found in a manifest. -// See https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1#Descriptor -type Descriptor struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - MediaType string `protobuf:"bytes,1,opt,name=media_type,json=mediaType,proto3" json:"media_type,omitempty"` - Digest string `protobuf:"bytes,2,opt,name=digest,proto3" json:"digest,omitempty"` - Size int64 `protobuf:"varint,3,opt,name=size,proto3" json:"size,omitempty"` - Annotations map[string]string `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *Descriptor) Reset() { - *x = Descriptor{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_descriptor_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Descriptor) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Descriptor) ProtoMessage() {} - -func (x *Descriptor) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_descriptor_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Descriptor.ProtoReflect.Descriptor instead. -func (*Descriptor) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescGZIP(), []int{0} -} - -func (x *Descriptor) GetMediaType() string { - if x != nil { - return x.MediaType - } - return "" -} - -func (x *Descriptor) GetDigest() string { - if x != nil { - return x.Digest - } - return "" -} - -func (x *Descriptor) GetSize() int64 { - if x != nil { - return x.Size - } - return 0 -} - -func (x *Descriptor) GetAnnotations() map[string]string { - if x != nil { - return x.Annotations - } - return nil -} - -var File_github_com_containerd_containerd_api_types_descriptor_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_descriptor_proto_rawDesc = []byte{ - 0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x64, 0x65, 0x73, - 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, - 0xe8, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x12, 0x1d, - 0x0a, 0x0a, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x54, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x64, 0x69, 0x67, 0x65, 0x73, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x64, - 0x69, 0x67, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x4f, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x41, 0x6e, 0x6e, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0b, 0x61, - 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x41, 0x6e, - 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, - 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescData = file_github_com_containerd_containerd_api_types_descriptor_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_descriptor_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_descriptor_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_github_com_containerd_containerd_api_types_descriptor_proto_goTypes = []interface{}{ - (*Descriptor)(nil), // 0: containerd.types.Descriptor - nil, // 1: containerd.types.Descriptor.AnnotationsEntry -} -var file_github_com_containerd_containerd_api_types_descriptor_proto_depIdxs = []int32{ - 1, // 0: containerd.types.Descriptor.annotations:type_name -> containerd.types.Descriptor.AnnotationsEntry - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_descriptor_proto_init() } -func file_github_com_containerd_containerd_api_types_descriptor_proto_init() { - if File_github_com_containerd_containerd_api_types_descriptor_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_descriptor_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Descriptor); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_descriptor_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_descriptor_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_descriptor_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_types_descriptor_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_descriptor_proto = out.File - file_github_com_containerd_containerd_api_types_descriptor_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_descriptor_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_descriptor_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/descriptor.proto b/vendor/github.com/containerd/containerd/api/types/descriptor.proto deleted file mode 100644 index faaf416dd..000000000 --- a/vendor/github.com/containerd/containerd/api/types/descriptor.proto +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.types; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -// Descriptor describes a blob in a content store. -// -// This descriptor can be used to reference content from an -// oci descriptor found in a manifest. -// See https://godoc.org/github.com/opencontainers/image-spec/specs-go/v1#Descriptor -message Descriptor { - string media_type = 1; - string digest = 2; - int64 size = 3; - map annotations = 5; -} diff --git a/vendor/github.com/containerd/containerd/api/types/doc.go b/vendor/github.com/containerd/containerd/api/types/doc.go deleted file mode 100644 index 475b465ed..000000000 --- a/vendor/github.com/containerd/containerd/api/types/doc.go +++ /dev/null @@ -1,17 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package types diff --git a/vendor/github.com/containerd/containerd/api/types/event.pb.go b/vendor/github.com/containerd/containerd/api/types/event.pb.go deleted file mode 100644 index 6ebe1e26d..000000000 --- a/vendor/github.com/containerd/containerd/api/types/event.pb.go +++ /dev/null @@ -1,209 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/event.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Envelope struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` - Topic string `protobuf:"bytes,3,opt,name=topic,proto3" json:"topic,omitempty"` - Event *anypb.Any `protobuf:"bytes,4,opt,name=event,proto3" json:"event,omitempty"` -} - -func (x *Envelope) Reset() { - *x = Envelope{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_event_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Envelope) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Envelope) ProtoMessage() {} - -func (x *Envelope) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_event_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Envelope.ProtoReflect.Descriptor instead. -func (*Envelope) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_event_proto_rawDescGZIP(), []int{0} -} - -func (x *Envelope) GetTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.Timestamp - } - return nil -} - -func (x *Envelope) GetNamespace() string { - if x != nil { - return x.Namespace - } - return "" -} - -func (x *Envelope) GetTopic() string { - if x != nil { - return x.Topic - } - return "" -} - -func (x *Envelope) GetEvent() *anypb.Any { - if x != nil { - return x.Event - } - return nil -} - -var File_github_com_containerd_containerd_api_types_event_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_event_proto_rawDesc = []byte{ - 0x0a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x76, 0x65, - 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x1a, 0x3a, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, - 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x70, 0x61, 0x74, 0x68, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0xaa, 0x01, 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, - 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, - 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, - 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x12, 0x2a, 0x0a, - 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, - 0x6e, 0x79, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x3a, 0x04, 0x80, 0xb9, 0x1f, 0x01, 0x42, - 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_event_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_event_proto_rawDescData = file_github_com_containerd_containerd_api_types_event_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_event_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_event_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_event_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_event_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_event_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_event_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_containerd_containerd_api_types_event_proto_goTypes = []interface{}{ - (*Envelope)(nil), // 0: containerd.types.Envelope - (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp - (*anypb.Any)(nil), // 2: google.protobuf.Any -} -var file_github_com_containerd_containerd_api_types_event_proto_depIdxs = []int32{ - 1, // 0: containerd.types.Envelope.timestamp:type_name -> google.protobuf.Timestamp - 2, // 1: containerd.types.Envelope.event:type_name -> google.protobuf.Any - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_event_proto_init() } -func file_github_com_containerd_containerd_api_types_event_proto_init() { - if File_github_com_containerd_containerd_api_types_event_proto != nil { - return - } - file_github_com_containerd_containerd_api_types_fieldpath_proto_init() - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_event_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Envelope); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_event_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_event_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_event_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_types_event_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_event_proto = out.File - file_github_com_containerd_containerd_api_types_event_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_event_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_event_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/event.proto b/vendor/github.com/containerd/containerd/api/types/event.proto deleted file mode 100644 index a73bc9d45..000000000 --- a/vendor/github.com/containerd/containerd/api/types/event.proto +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.types; - -import "github.com/containerd/containerd/api/types/fieldpath.proto"; -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -message Envelope { - option (containerd.types.fieldpath) = true; - google.protobuf.Timestamp timestamp = 1; - string namespace = 2; - string topic = 3; - google.protobuf.Any event = 4; -} diff --git a/vendor/github.com/containerd/containerd/api/types/fieldpath.pb.go b/vendor/github.com/containerd/containerd/api/types/fieldpath.pb.go deleted file mode 100644 index 0f8feb415..000000000 --- a/vendor/github.com/containerd/containerd/api/types/fieldpath.pb.go +++ /dev/null @@ -1,144 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/fieldpath.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - descriptorpb "google.golang.org/protobuf/types/descriptorpb" - reflect "reflect" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -var file_github_com_containerd_containerd_api_types_fieldpath_proto_extTypes = []protoimpl.ExtensionInfo{ - { - ExtendedType: (*descriptorpb.FileOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 63300, - Name: "containerd.types.fieldpath_all", - Tag: "varint,63300,opt,name=fieldpath_all", - Filename: "github.com/containerd/containerd/api/types/fieldpath.proto", - }, - { - ExtendedType: (*descriptorpb.MessageOptions)(nil), - ExtensionType: (*bool)(nil), - Field: 64400, - Name: "containerd.types.fieldpath", - Tag: "varint,64400,opt,name=fieldpath", - Filename: "github.com/containerd/containerd/api/types/fieldpath.proto", - }, -} - -// Extension fields to descriptorpb.FileOptions. -var ( - // optional bool fieldpath_all = 63300; - E_FieldpathAll = &file_github_com_containerd_containerd_api_types_fieldpath_proto_extTypes[0] -) - -// Extension fields to descriptorpb.MessageOptions. -var ( - // optional bool fieldpath = 64400; - E_Fieldpath = &file_github_com_containerd_containerd_api_types_fieldpath_proto_extTypes[1] -) - -var File_github_com_containerd_containerd_api_types_fieldpath_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_fieldpath_proto_rawDesc = []byte{ - 0x0a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x65, - 0x6c, 0x64, 0x70, 0x61, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x1a, 0x20, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, - 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x3a, 0x46, 0x0a, 0x0d, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x61, 0x6c, - 0x6c, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0xc4, 0xee, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x70, 0x61, - 0x74, 0x68, 0x41, 0x6c, 0x6c, 0x88, 0x01, 0x01, 0x3a, 0x42, 0x0a, 0x09, 0x66, 0x69, 0x65, 0x6c, - 0x64, 0x70, 0x61, 0x74, 0x68, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x90, 0xf7, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, - 0x66, 0x69, 0x65, 0x6c, 0x64, 0x70, 0x61, 0x74, 0x68, 0x88, 0x01, 0x01, 0x42, 0x32, 0x5a, 0x30, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var file_github_com_containerd_containerd_api_types_fieldpath_proto_goTypes = []interface{}{ - (*descriptorpb.FileOptions)(nil), // 0: google.protobuf.FileOptions - (*descriptorpb.MessageOptions)(nil), // 1: google.protobuf.MessageOptions -} -var file_github_com_containerd_containerd_api_types_fieldpath_proto_depIdxs = []int32{ - 0, // 0: containerd.types.fieldpath_all:extendee -> google.protobuf.FileOptions - 1, // 1: containerd.types.fieldpath:extendee -> google.protobuf.MessageOptions - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 0, // [0:2] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_fieldpath_proto_init() } -func file_github_com_containerd_containerd_api_types_fieldpath_proto_init() { - if File_github_com_containerd_containerd_api_types_fieldpath_proto != nil { - return - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_fieldpath_proto_rawDesc, - NumEnums: 0, - NumMessages: 0, - NumExtensions: 2, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_fieldpath_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_fieldpath_proto_depIdxs, - ExtensionInfos: file_github_com_containerd_containerd_api_types_fieldpath_proto_extTypes, - }.Build() - File_github_com_containerd_containerd_api_types_fieldpath_proto = out.File - file_github_com_containerd_containerd_api_types_fieldpath_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_fieldpath_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_fieldpath_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/fieldpath.proto b/vendor/github.com/containerd/containerd/api/types/fieldpath.proto deleted file mode 100644 index 8b290842b..000000000 --- a/vendor/github.com/containerd/containerd/api/types/fieldpath.proto +++ /dev/null @@ -1,42 +0,0 @@ -// Protocol Buffers for Go with Gadgets -// -// Copyright (c) 2013, The GoGo Authors. All rights reserved. -// http://github.com/gogo/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; -package containerd.types; - -import "google/protobuf/descriptor.proto"; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -extend google.protobuf.FileOptions { - optional bool fieldpath_all = 63300; -} - -extend google.protobuf.MessageOptions { - optional bool fieldpath = 64400; -} diff --git a/vendor/github.com/containerd/containerd/api/types/introspection.pb.go b/vendor/github.com/containerd/containerd/api/types/introspection.pb.go deleted file mode 100644 index 2f9c2ac44..000000000 --- a/vendor/github.com/containerd/containerd/api/types/introspection.pb.go +++ /dev/null @@ -1,375 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/introspection.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type RuntimeRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - RuntimePath string `protobuf:"bytes,1,opt,name=runtime_path,json=runtimePath,proto3" json:"runtime_path,omitempty"` - // Options correspond to CreateTaskRequest.options. - // This is needed to pass the runc binary path, etc. - Options *anypb.Any `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` -} - -func (x *RuntimeRequest) Reset() { - *x = RuntimeRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RuntimeRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RuntimeRequest) ProtoMessage() {} - -func (x *RuntimeRequest) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RuntimeRequest.ProtoReflect.Descriptor instead. -func (*RuntimeRequest) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP(), []int{0} -} - -func (x *RuntimeRequest) GetRuntimePath() string { - if x != nil { - return x.RuntimePath - } - return "" -} - -func (x *RuntimeRequest) GetOptions() *anypb.Any { - if x != nil { - return x.Options - } - return nil -} - -type RuntimeVersion struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` - Revision string `protobuf:"bytes,2,opt,name=revision,proto3" json:"revision,omitempty"` -} - -func (x *RuntimeVersion) Reset() { - *x = RuntimeVersion{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RuntimeVersion) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RuntimeVersion) ProtoMessage() {} - -func (x *RuntimeVersion) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RuntimeVersion.ProtoReflect.Descriptor instead. -func (*RuntimeVersion) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP(), []int{1} -} - -func (x *RuntimeVersion) GetVersion() string { - if x != nil { - return x.Version - } - return "" -} - -func (x *RuntimeVersion) GetRevision() string { - if x != nil { - return x.Revision - } - return "" -} - -type RuntimeInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - Version *RuntimeVersion `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` - // Options correspond to RuntimeInfoRequest.Options (contains runc binary path, etc.) - Options *anypb.Any `protobuf:"bytes,3,opt,name=options,proto3" json:"options,omitempty"` - // OCI-compatible runtimes should use https://github.com/opencontainers/runtime-spec/blob/main/features.md - Features *anypb.Any `protobuf:"bytes,4,opt,name=features,proto3" json:"features,omitempty"` - // Annotations of the shim. Irrelevant to features.Annotations. - Annotations map[string]string `protobuf:"bytes,5,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` -} - -func (x *RuntimeInfo) Reset() { - *x = RuntimeInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *RuntimeInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*RuntimeInfo) ProtoMessage() {} - -func (x *RuntimeInfo) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use RuntimeInfo.ProtoReflect.Descriptor instead. -func (*RuntimeInfo) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP(), []int{2} -} - -func (x *RuntimeInfo) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *RuntimeInfo) GetVersion() *RuntimeVersion { - if x != nil { - return x.Version - } - return nil -} - -func (x *RuntimeInfo) GetOptions() *anypb.Any { - if x != nil { - return x.Options - } - return nil -} - -func (x *RuntimeInfo) GetFeatures() *anypb.Any { - if x != nil { - return x.Features - } - return nil -} - -func (x *RuntimeInfo) GetAnnotations() map[string]string { - if x != nil { - return x.Annotations - } - return nil -} - -var File_github_com_containerd_containerd_api_types_introspection_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc = []byte{ - 0x0a, 0x3e, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x69, 0x6e, 0x74, - 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x12, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x63, 0x0a, - 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x50, 0x61, - 0x74, 0x68, 0x12, 0x2e, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x22, 0x46, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1a, - 0x0a, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd1, 0x02, 0x0a, 0x0b, 0x52, - 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, - 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2e, 0x0a, 0x07, 0x6f, 0x70, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, - 0x79, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x08, 0x66, 0x65, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, - 0x6e, 0x79, 0x52, 0x08, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x50, 0x0a, 0x0b, - 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x49, 0x6e, 0x66, 0x6f, - 0x2e, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x3e, - 0x0a, 0x10, 0x41, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x32, - 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_introspection_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData = file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_introspection_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_introspection_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_introspection_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_github_com_containerd_containerd_api_types_introspection_proto_goTypes = []interface{}{ - (*RuntimeRequest)(nil), // 0: containerd.types.RuntimeRequest - (*RuntimeVersion)(nil), // 1: containerd.types.RuntimeVersion - (*RuntimeInfo)(nil), // 2: containerd.types.RuntimeInfo - nil, // 3: containerd.types.RuntimeInfo.AnnotationsEntry - (*anypb.Any)(nil), // 4: google.protobuf.Any -} -var file_github_com_containerd_containerd_api_types_introspection_proto_depIdxs = []int32{ - 4, // 0: containerd.types.RuntimeRequest.options:type_name -> google.protobuf.Any - 1, // 1: containerd.types.RuntimeInfo.version:type_name -> containerd.types.RuntimeVersion - 4, // 2: containerd.types.RuntimeInfo.options:type_name -> google.protobuf.Any - 4, // 3: containerd.types.RuntimeInfo.features:type_name -> google.protobuf.Any - 3, // 4: containerd.types.RuntimeInfo.annotations:type_name -> containerd.types.RuntimeInfo.AnnotationsEntry - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_introspection_proto_init() } -func file_github_com_containerd_containerd_api_types_introspection_proto_init() { - if File_github_com_containerd_containerd_api_types_introspection_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RuntimeRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RuntimeVersion); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*RuntimeInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_introspection_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_introspection_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_types_introspection_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_introspection_proto = out.File - file_github_com_containerd_containerd_api_types_introspection_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_introspection_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_introspection_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/introspection.proto b/vendor/github.com/containerd/containerd/api/types/introspection.proto deleted file mode 100644 index 8f3fcb5a4..000000000 --- a/vendor/github.com/containerd/containerd/api/types/introspection.proto +++ /dev/null @@ -1,46 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.types; - -import "google/protobuf/any.proto"; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -message RuntimeRequest { - string runtime_path = 1; - // Options correspond to CreateTaskRequest.options. - // This is needed to pass the runc binary path, etc. - google.protobuf.Any options = 2; -} - -message RuntimeVersion { - string version = 1; - string revision = 2; -} - -message RuntimeInfo { - string name = 1; - RuntimeVersion version = 2; - // Options correspond to RuntimeInfoRequest.Options (contains runc binary path, etc.) - google.protobuf.Any options = 3; - // OCI-compatible runtimes should use https://github.com/opencontainers/runtime-spec/blob/main/features.md - google.protobuf.Any features = 4; - // Annotations of the shim. Irrelevant to features.Annotations. - map annotations = 5; -} diff --git a/vendor/github.com/containerd/containerd/api/types/metrics.pb.go b/vendor/github.com/containerd/containerd/api/types/metrics.pb.go deleted file mode 100644 index b18ce1c5b..000000000 --- a/vendor/github.com/containerd/containerd/api/types/metrics.pb.go +++ /dev/null @@ -1,194 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/metrics.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Metric struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` - ID string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Data *anypb.Any `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` -} - -func (x *Metric) Reset() { - *x = Metric{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_metrics_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Metric) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Metric) ProtoMessage() {} - -func (x *Metric) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_metrics_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Metric.ProtoReflect.Descriptor instead. -func (*Metric) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_metrics_proto_rawDescGZIP(), []int{0} -} - -func (x *Metric) GetTimestamp() *timestamppb.Timestamp { - if x != nil { - return x.Timestamp - } - return nil -} - -func (x *Metric) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *Metric) GetData() *anypb.Any { - if x != nil { - return x.Data - } - return nil -} - -var File_github_com_containerd_containerd_api_types_metrics_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_metrics_proto_rawDesc = []byte{ - 0x0a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, - 0x72, 0x69, 0x63, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x1a, 0x19, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7c, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x12, 0x38, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x28, 0x0a, 0x04, - 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_metrics_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_metrics_proto_rawDescData = file_github_com_containerd_containerd_api_types_metrics_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_metrics_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_metrics_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_metrics_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_metrics_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_metrics_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_containerd_containerd_api_types_metrics_proto_goTypes = []interface{}{ - (*Metric)(nil), // 0: containerd.types.Metric - (*timestamppb.Timestamp)(nil), // 1: google.protobuf.Timestamp - (*anypb.Any)(nil), // 2: google.protobuf.Any -} -var file_github_com_containerd_containerd_api_types_metrics_proto_depIdxs = []int32{ - 1, // 0: containerd.types.Metric.timestamp:type_name -> google.protobuf.Timestamp - 2, // 1: containerd.types.Metric.data:type_name -> google.protobuf.Any - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_metrics_proto_init() } -func file_github_com_containerd_containerd_api_types_metrics_proto_init() { - if File_github_com_containerd_containerd_api_types_metrics_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_metrics_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Metric); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_metrics_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_metrics_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_metrics_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_types_metrics_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_metrics_proto = out.File - file_github_com_containerd_containerd_api_types_metrics_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_metrics_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_metrics_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/metrics.proto b/vendor/github.com/containerd/containerd/api/types/metrics.proto deleted file mode 100644 index 3e6a7751e..000000000 --- a/vendor/github.com/containerd/containerd/api/types/metrics.proto +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.types; - -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -message Metric { - google.protobuf.Timestamp timestamp = 1; - string id = 2; - google.protobuf.Any data = 3; -} diff --git a/vendor/github.com/containerd/containerd/api/types/mount.pb.go b/vendor/github.com/containerd/containerd/api/types/mount.pb.go deleted file mode 100644 index ff77a7d7b..000000000 --- a/vendor/github.com/containerd/containerd/api/types/mount.pb.go +++ /dev/null @@ -1,202 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/mount.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Mount describes mounts for a container. -// -// This type is the lingua franca of ContainerD. All services provide mounts -// to be used with the container at creation time. -// -// The Mount type follows the structure of the mount syscall, including a type, -// source, target and options. -type Mount struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Type defines the nature of the mount. - Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` - // Source specifies the name of the mount. Depending on mount type, this - // may be a volume name or a host path, or even ignored. - Source string `protobuf:"bytes,2,opt,name=source,proto3" json:"source,omitempty"` - // Target path in container - Target string `protobuf:"bytes,3,opt,name=target,proto3" json:"target,omitempty"` - // Options specifies zero or more fstab style mount options. - Options []string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty"` -} - -func (x *Mount) Reset() { - *x = Mount{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_mount_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Mount) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Mount) ProtoMessage() {} - -func (x *Mount) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_mount_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Mount.ProtoReflect.Descriptor instead. -func (*Mount) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_mount_proto_rawDescGZIP(), []int{0} -} - -func (x *Mount) GetType() string { - if x != nil { - return x.Type - } - return "" -} - -func (x *Mount) GetSource() string { - if x != nil { - return x.Source - } - return "" -} - -func (x *Mount) GetTarget() string { - if x != nil { - return x.Target - } - return "" -} - -func (x *Mount) GetOptions() []string { - if x != nil { - return x.Options - } - return nil -} - -var File_github_com_containerd_containerd_api_types_mount_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_mount_proto_rawDesc = []byte{ - 0x0a, 0x36, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x6d, 0x6f, 0x75, - 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x65, 0x0a, 0x05, 0x4d, 0x6f, - 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, - 0x16, 0x0a, 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x06, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_mount_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_mount_proto_rawDescData = file_github_com_containerd_containerd_api_types_mount_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_mount_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_mount_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_mount_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_mount_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_mount_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_mount_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_containerd_containerd_api_types_mount_proto_goTypes = []interface{}{ - (*Mount)(nil), // 0: containerd.types.Mount -} -var file_github_com_containerd_containerd_api_types_mount_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_mount_proto_init() } -func file_github_com_containerd_containerd_api_types_mount_proto_init() { - if File_github_com_containerd_containerd_api_types_mount_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_mount_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Mount); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_mount_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_mount_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_mount_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_types_mount_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_mount_proto = out.File - file_github_com_containerd_containerd_api_types_mount_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_mount_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_mount_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/mount.proto b/vendor/github.com/containerd/containerd/api/types/mount.proto deleted file mode 100644 index 54e0a0cdd..000000000 --- a/vendor/github.com/containerd/containerd/api/types/mount.proto +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.types; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -// Mount describes mounts for a container. -// -// This type is the lingua franca of ContainerD. All services provide mounts -// to be used with the container at creation time. -// -// The Mount type follows the structure of the mount syscall, including a type, -// source, target and options. -message Mount { - // Type defines the nature of the mount. - string type = 1; - - // Source specifies the name of the mount. Depending on mount type, this - // may be a volume name or a host path, or even ignored. - string source = 2; - - // Target path in container - string target = 3; - - // Options specifies zero or more fstab style mount options. - repeated string options = 4; -} diff --git a/vendor/github.com/containerd/containerd/api/types/platform.pb.go b/vendor/github.com/containerd/containerd/api/types/platform.pb.go deleted file mode 100644 index daa62b834..000000000 --- a/vendor/github.com/containerd/containerd/api/types/platform.pb.go +++ /dev/null @@ -1,194 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/platform.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Platform follows the structure of the OCI platform specification, from -// descriptors. -type Platform struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - OS string `protobuf:"bytes,1,opt,name=os,proto3" json:"os,omitempty"` - Architecture string `protobuf:"bytes,2,opt,name=architecture,proto3" json:"architecture,omitempty"` - Variant string `protobuf:"bytes,3,opt,name=variant,proto3" json:"variant,omitempty"` - OSVersion string `protobuf:"bytes,4,opt,name=os_version,json=osVersion,proto3" json:"os_version,omitempty"` -} - -func (x *Platform) Reset() { - *x = Platform{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_platform_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Platform) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Platform) ProtoMessage() {} - -func (x *Platform) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_platform_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Platform.ProtoReflect.Descriptor instead. -func (*Platform) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_platform_proto_rawDescGZIP(), []int{0} -} - -func (x *Platform) GetOS() string { - if x != nil { - return x.OS - } - return "" -} - -func (x *Platform) GetArchitecture() string { - if x != nil { - return x.Architecture - } - return "" -} - -func (x *Platform) GetVariant() string { - if x != nil { - return x.Variant - } - return "" -} - -func (x *Platform) GetOsVersion() string { - if x != nil { - return x.OSVersion - } - return "" -} - -var File_github_com_containerd_containerd_api_types_platform_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_platform_proto_rawDesc = []byte{ - 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x70, 0x6c, 0x61, - 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x22, 0x77, 0x0a, - 0x08, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x6f, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x61, 0x72, 0x63, - 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x76, 0x61, 0x72, 0x69, 0x61, 0x6e, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x73, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6f, 0x73, 0x56, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_platform_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_platform_proto_rawDescData = file_github_com_containerd_containerd_api_types_platform_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_platform_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_platform_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_platform_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_platform_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_platform_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_platform_proto_msgTypes = make([]protoimpl.MessageInfo, 1) -var file_github_com_containerd_containerd_api_types_platform_proto_goTypes = []interface{}{ - (*Platform)(nil), // 0: containerd.types.Platform -} -var file_github_com_containerd_containerd_api_types_platform_proto_depIdxs = []int32{ - 0, // [0:0] is the sub-list for method output_type - 0, // [0:0] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_platform_proto_init() } -func file_github_com_containerd_containerd_api_types_platform_proto_init() { - if File_github_com_containerd_containerd_api_types_platform_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_platform_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Platform); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_platform_proto_rawDesc, - NumEnums: 0, - NumMessages: 1, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_platform_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_platform_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_types_platform_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_platform_proto = out.File - file_github_com_containerd_containerd_api_types_platform_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_platform_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_platform_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/platform.proto b/vendor/github.com/containerd/containerd/api/types/platform.proto deleted file mode 100644 index 0b9180016..000000000 --- a/vendor/github.com/containerd/containerd/api/types/platform.proto +++ /dev/null @@ -1,30 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.types; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -// Platform follows the structure of the OCI platform specification, from -// descriptors. -message Platform { - string os = 1; - string architecture = 2; - string variant = 3; - string os_version = 4; -} diff --git a/vendor/github.com/containerd/containerd/api/types/platform_helpers.go b/vendor/github.com/containerd/containerd/api/types/platform_helpers.go deleted file mode 100644 index d8c1a6877..000000000 --- a/vendor/github.com/containerd/containerd/api/types/platform_helpers.go +++ /dev/null @@ -1,49 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package types - -import oci "github.com/opencontainers/image-spec/specs-go/v1" - -// OCIPlatformToProto converts from a slice of OCI [specs.Platform] to a -// slice of the protobuf definition [Platform]. -func OCIPlatformToProto(platforms []oci.Platform) []*Platform { - ap := make([]*Platform, len(platforms)) - for i := range platforms { - ap[i] = &Platform{ - OS: platforms[i].OS, - OSVersion: platforms[i].OSVersion, - Architecture: platforms[i].Architecture, - Variant: platforms[i].Variant, - } - } - return ap -} - -// OCIPlatformFromProto converts a slice of the protobuf definition [Platform] -// to a slice of OCI [specs.Platform]. -func OCIPlatformFromProto(platforms []*Platform) []oci.Platform { - op := make([]oci.Platform, len(platforms)) - for i := range platforms { - op[i] = oci.Platform{ - OS: platforms[i].OS, - OSVersion: platforms[i].OSVersion, - Architecture: platforms[i].Architecture, - Variant: platforms[i].Variant, - } - } - return op -} diff --git a/vendor/github.com/containerd/containerd/api/types/sandbox.pb.go b/vendor/github.com/containerd/containerd/api/types/sandbox.pb.go deleted file mode 100644 index 77888bf33..000000000 --- a/vendor/github.com/containerd/containerd/api/types/sandbox.pb.go +++ /dev/null @@ -1,357 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/sandbox.proto - -package types - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// Sandbox represents a sandbox metadata object that keeps all info required by controller to -// work with a particular instance. -type Sandbox struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // SandboxID is a unique instance identifier within namespace - SandboxID string `protobuf:"bytes,1,opt,name=sandbox_id,json=sandboxId,proto3" json:"sandbox_id,omitempty"` - // Runtime specifies which runtime to use for executing this container. - Runtime *Sandbox_Runtime `protobuf:"bytes,2,opt,name=runtime,proto3" json:"runtime,omitempty"` - // Spec is sandbox configuration (kin of OCI runtime spec), spec's data will be written to a config.json file in the - // bundle directory (similary to OCI spec). - Spec *anypb.Any `protobuf:"bytes,3,opt,name=spec,proto3" json:"spec,omitempty"` - // Labels provides an area to include arbitrary data on containers. - Labels map[string]string `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // CreatedAt is the time the container was first created. - CreatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - // UpdatedAt is the last time the container was mutated. - UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` - // Extensions allow clients to provide optional blobs that can be handled by runtime. - Extensions map[string]*anypb.Any `protobuf:"bytes,7,rep,name=extensions,proto3" json:"extensions,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - // Sandboxer is the name of the sandbox controller who manages the sandbox. - Sandboxer string `protobuf:"bytes,10,opt,name=sandboxer,proto3" json:"sandboxer,omitempty"` -} - -func (x *Sandbox) Reset() { - *x = Sandbox{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Sandbox) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Sandbox) ProtoMessage() {} - -func (x *Sandbox) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Sandbox.ProtoReflect.Descriptor instead. -func (*Sandbox) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescGZIP(), []int{0} -} - -func (x *Sandbox) GetSandboxID() string { - if x != nil { - return x.SandboxID - } - return "" -} - -func (x *Sandbox) GetRuntime() *Sandbox_Runtime { - if x != nil { - return x.Runtime - } - return nil -} - -func (x *Sandbox) GetSpec() *anypb.Any { - if x != nil { - return x.Spec - } - return nil -} - -func (x *Sandbox) GetLabels() map[string]string { - if x != nil { - return x.Labels - } - return nil -} - -func (x *Sandbox) GetCreatedAt() *timestamppb.Timestamp { - if x != nil { - return x.CreatedAt - } - return nil -} - -func (x *Sandbox) GetUpdatedAt() *timestamppb.Timestamp { - if x != nil { - return x.UpdatedAt - } - return nil -} - -func (x *Sandbox) GetExtensions() map[string]*anypb.Any { - if x != nil { - return x.Extensions - } - return nil -} - -func (x *Sandbox) GetSandboxer() string { - if x != nil { - return x.Sandboxer - } - return "" -} - -type Sandbox_Runtime struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // Name is the name of the runtime. - Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // Options specify additional runtime initialization options for the shim (this data will be available in StartShim). - // Typically this data expected to be runtime shim implementation specific. - Options *anypb.Any `protobuf:"bytes,2,opt,name=options,proto3" json:"options,omitempty"` -} - -func (x *Sandbox_Runtime) Reset() { - *x = Sandbox_Runtime{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Sandbox_Runtime) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Sandbox_Runtime) ProtoMessage() {} - -func (x *Sandbox_Runtime) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Sandbox_Runtime.ProtoReflect.Descriptor instead. -func (*Sandbox_Runtime) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescGZIP(), []int{0, 0} -} - -func (x *Sandbox_Runtime) GetName() string { - if x != nil { - return x.Name - } - return "" -} - -func (x *Sandbox_Runtime) GetOptions() *anypb.Any { - if x != nil { - return x.Options - } - return nil -} - -var File_github_com_containerd_containerd_api_types_sandbox_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_sandbox_proto_rawDesc = []byte{ - 0x0a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x73, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x1a, 0x19, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, - 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8c, 0x05, 0x0a, 0x07, 0x53, 0x61, 0x6e, - 0x64, 0x62, 0x6f, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x5f, - 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, 0x61, 0x6e, 0x64, 0x62, 0x6f, - 0x78, 0x49, 0x64, 0x12, 0x3b, 0x0a, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, - 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x07, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x12, 0x28, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x3d, 0x0a, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x12, 0x39, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, - 0x49, 0x0a, 0x0a, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x2e, 0x45, - 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, - 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x61, - 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, - 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x65, 0x72, 0x1a, 0x4d, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, - 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2e, 0x0a, 0x07, 0x6f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x07, - 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x1a, 0x53, 0x0a, 0x0f, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x32, 0x5a, 0x30, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, - 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x3b, 0x74, 0x79, 0x70, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescData = file_github_com_containerd_containerd_api_types_sandbox_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_sandbox_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_github_com_containerd_containerd_api_types_sandbox_proto_goTypes = []interface{}{ - (*Sandbox)(nil), // 0: containerd.types.Sandbox - (*Sandbox_Runtime)(nil), // 1: containerd.types.Sandbox.Runtime - nil, // 2: containerd.types.Sandbox.LabelsEntry - nil, // 3: containerd.types.Sandbox.ExtensionsEntry - (*anypb.Any)(nil), // 4: google.protobuf.Any - (*timestamppb.Timestamp)(nil), // 5: google.protobuf.Timestamp -} -var file_github_com_containerd_containerd_api_types_sandbox_proto_depIdxs = []int32{ - 1, // 0: containerd.types.Sandbox.runtime:type_name -> containerd.types.Sandbox.Runtime - 4, // 1: containerd.types.Sandbox.spec:type_name -> google.protobuf.Any - 2, // 2: containerd.types.Sandbox.labels:type_name -> containerd.types.Sandbox.LabelsEntry - 5, // 3: containerd.types.Sandbox.created_at:type_name -> google.protobuf.Timestamp - 5, // 4: containerd.types.Sandbox.updated_at:type_name -> google.protobuf.Timestamp - 3, // 5: containerd.types.Sandbox.extensions:type_name -> containerd.types.Sandbox.ExtensionsEntry - 4, // 6: containerd.types.Sandbox.Runtime.options:type_name -> google.protobuf.Any - 4, // 7: containerd.types.Sandbox.ExtensionsEntry.value:type_name -> google.protobuf.Any - 8, // [8:8] is the sub-list for method output_type - 8, // [8:8] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_sandbox_proto_init() } -func file_github_com_containerd_containerd_api_types_sandbox_proto_init() { - if File_github_com_containerd_containerd_api_types_sandbox_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Sandbox); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Sandbox_Runtime); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_sandbox_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_sandbox_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_sandbox_proto_depIdxs, - MessageInfos: file_github_com_containerd_containerd_api_types_sandbox_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_sandbox_proto = out.File - file_github_com_containerd_containerd_api_types_sandbox_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_sandbox_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_sandbox_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/sandbox.proto b/vendor/github.com/containerd/containerd/api/types/sandbox.proto deleted file mode 100644 index b0bf233b9..000000000 --- a/vendor/github.com/containerd/containerd/api/types/sandbox.proto +++ /dev/null @@ -1,54 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.types; - -import "google/protobuf/any.proto"; -import "google/protobuf/timestamp.proto"; - -option go_package = "github.com/containerd/containerd/api/types;types"; - -// Sandbox represents a sandbox metadata object that keeps all info required by controller to -// work with a particular instance. -message Sandbox { - // SandboxID is a unique instance identifier within namespace - string sandbox_id = 1; - message Runtime { - // Name is the name of the runtime. - string name = 1; - // Options specify additional runtime initialization options for the shim (this data will be available in StartShim). - // Typically this data expected to be runtime shim implementation specific. - google.protobuf.Any options = 2; - } - // Runtime specifies which runtime to use for executing this container. - Runtime runtime = 2; - // Spec is sandbox configuration (kin of OCI runtime spec), spec's data will be written to a config.json file in the - // bundle directory (similary to OCI spec). - google.protobuf.Any spec = 3; - // Labels provides an area to include arbitrary data on containers. - map labels = 4; - // CreatedAt is the time the container was first created. - google.protobuf.Timestamp created_at = 5; - // UpdatedAt is the last time the container was mutated. - google.protobuf.Timestamp updated_at = 6; - // Extensions allow clients to provide optional blobs that can be handled by runtime. - map extensions = 7; - // Sandboxer is the name of the sandbox controller who manages the sandbox. - string sandboxer = 10; - -} diff --git a/vendor/github.com/containerd/containerd/api/types/task/doc.go b/vendor/github.com/containerd/containerd/api/types/task/doc.go deleted file mode 100644 index e10c7a469..000000000 --- a/vendor/github.com/containerd/containerd/api/types/task/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// Package task defines the task service. -package task diff --git a/vendor/github.com/containerd/containerd/api/types/task/task.pb.go b/vendor/github.com/containerd/containerd/api/types/task/task.pb.go deleted file mode 100644 index 5c58d1ef1..000000000 --- a/vendor/github.com/containerd/containerd/api/types/task/task.pb.go +++ /dev/null @@ -1,406 +0,0 @@ -// -//Copyright The containerd Authors. -// -//Licensed under the Apache License, Version 2.0 (the "License"); -//you may not use this file except in compliance with the License. -//You may obtain a copy of the License at -// -//http://www.apache.org/licenses/LICENSE-2.0 -// -//Unless required by applicable law or agreed to in writing, software -//distributed under the License is distributed on an "AS IS" BASIS, -//WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -//See the License for the specific language governing permissions and -//limitations under the License. - -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/containerd/api/types/task/task.proto - -package task - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - anypb "google.golang.org/protobuf/types/known/anypb" - timestamppb "google.golang.org/protobuf/types/known/timestamppb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Status int32 - -const ( - Status_UNKNOWN Status = 0 - Status_CREATED Status = 1 - Status_RUNNING Status = 2 - Status_STOPPED Status = 3 - Status_PAUSED Status = 4 - Status_PAUSING Status = 5 -) - -// Enum value maps for Status. -var ( - Status_name = map[int32]string{ - 0: "UNKNOWN", - 1: "CREATED", - 2: "RUNNING", - 3: "STOPPED", - 4: "PAUSED", - 5: "PAUSING", - } - Status_value = map[string]int32{ - "UNKNOWN": 0, - "CREATED": 1, - "RUNNING": 2, - "STOPPED": 3, - "PAUSED": 4, - "PAUSING": 5, - } -) - -func (x Status) Enum() *Status { - p := new(Status) - *p = x - return p -} - -func (x Status) String() string { - return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) -} - -func (Status) Descriptor() protoreflect.EnumDescriptor { - return file_github_com_containerd_containerd_api_types_task_task_proto_enumTypes[0].Descriptor() -} - -func (Status) Type() protoreflect.EnumType { - return &file_github_com_containerd_containerd_api_types_task_task_proto_enumTypes[0] -} - -func (x Status) Number() protoreflect.EnumNumber { - return protoreflect.EnumNumber(x) -} - -// Deprecated: Use Status.Descriptor instead. -func (Status) EnumDescriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_task_task_proto_rawDescGZIP(), []int{0} -} - -type Process struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - ContainerID string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"` - ID string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Pid uint32 `protobuf:"varint,3,opt,name=pid,proto3" json:"pid,omitempty"` - Status Status `protobuf:"varint,4,opt,name=status,proto3,enum=containerd.v1.types.Status" json:"status,omitempty"` - Stdin string `protobuf:"bytes,5,opt,name=stdin,proto3" json:"stdin,omitempty"` - Stdout string `protobuf:"bytes,6,opt,name=stdout,proto3" json:"stdout,omitempty"` - Stderr string `protobuf:"bytes,7,opt,name=stderr,proto3" json:"stderr,omitempty"` - Terminal bool `protobuf:"varint,8,opt,name=terminal,proto3" json:"terminal,omitempty"` - ExitStatus uint32 `protobuf:"varint,9,opt,name=exit_status,json=exitStatus,proto3" json:"exit_status,omitempty"` - ExitedAt *timestamppb.Timestamp `protobuf:"bytes,10,opt,name=exited_at,json=exitedAt,proto3" json:"exited_at,omitempty"` -} - -func (x *Process) Reset() { - *x = Process{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Process) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Process) ProtoMessage() {} - -func (x *Process) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Process.ProtoReflect.Descriptor instead. -func (*Process) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_task_task_proto_rawDescGZIP(), []int{0} -} - -func (x *Process) GetContainerID() string { - if x != nil { - return x.ContainerID - } - return "" -} - -func (x *Process) GetID() string { - if x != nil { - return x.ID - } - return "" -} - -func (x *Process) GetPid() uint32 { - if x != nil { - return x.Pid - } - return 0 -} - -func (x *Process) GetStatus() Status { - if x != nil { - return x.Status - } - return Status_UNKNOWN -} - -func (x *Process) GetStdin() string { - if x != nil { - return x.Stdin - } - return "" -} - -func (x *Process) GetStdout() string { - if x != nil { - return x.Stdout - } - return "" -} - -func (x *Process) GetStderr() string { - if x != nil { - return x.Stderr - } - return "" -} - -func (x *Process) GetTerminal() bool { - if x != nil { - return x.Terminal - } - return false -} - -func (x *Process) GetExitStatus() uint32 { - if x != nil { - return x.ExitStatus - } - return 0 -} - -func (x *Process) GetExitedAt() *timestamppb.Timestamp { - if x != nil { - return x.ExitedAt - } - return nil -} - -type ProcessInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - // PID is the process ID. - Pid uint32 `protobuf:"varint,1,opt,name=pid,proto3" json:"pid,omitempty"` - // Info contains additional process information. - // - // Info varies by platform. - Info *anypb.Any `protobuf:"bytes,2,opt,name=info,proto3" json:"info,omitempty"` -} - -func (x *ProcessInfo) Reset() { - *x = ProcessInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *ProcessInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*ProcessInfo) ProtoMessage() {} - -func (x *ProcessInfo) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use ProcessInfo.ProtoReflect.Descriptor instead. -func (*ProcessInfo) Descriptor() ([]byte, []int) { - return file_github_com_containerd_containerd_api_types_task_task_proto_rawDescGZIP(), []int{1} -} - -func (x *ProcessInfo) GetPid() uint32 { - if x != nil { - return x.Pid - } - return 0 -} - -func (x *ProcessInfo) GetInfo() *anypb.Any { - if x != nil { - return x.Info - } - return nil -} - -var File_github_com_containerd_containerd_api_types_task_task_proto protoreflect.FileDescriptor - -var file_github_com_containerd_containerd_api_types_task_task_proto_rawDesc = []byte{ - 0x0a, 0x3a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x74, 0x61, 0x73, - 0x6b, 0x2f, 0x74, 0x61, 0x73, 0x6b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x02, - 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x0e, 0x0a, 0x02, - 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, - 0x70, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x33, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x76, 0x31, 0x2e, 0x74, - 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x64, 0x69, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, - 0x6f, 0x75, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x6f, 0x75, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x73, 0x74, 0x64, 0x65, 0x72, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x74, 0x65, 0x72, - 0x6d, 0x69, 0x6e, 0x61, 0x6c, 0x12, 0x1f, 0x0a, 0x0b, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x65, 0x78, 0x69, 0x74, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x37, 0x0a, 0x09, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x08, 0x65, 0x78, 0x69, 0x74, 0x65, 0x64, 0x41, 0x74, 0x22, - 0x49, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, - 0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, - 0x12, 0x28, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x2a, 0x55, 0x0a, 0x06, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, - 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, - 0x0a, 0x07, 0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x53, - 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x41, 0x55, 0x53, - 0x45, 0x44, 0x10, 0x04, 0x12, 0x0b, 0x0a, 0x07, 0x50, 0x41, 0x55, 0x53, 0x49, 0x4e, 0x47, 0x10, - 0x05, 0x42, 0x31, 0x5a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, - 0x74, 0x61, 0x73, 0x6b, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_github_com_containerd_containerd_api_types_task_task_proto_rawDescOnce sync.Once - file_github_com_containerd_containerd_api_types_task_task_proto_rawDescData = file_github_com_containerd_containerd_api_types_task_task_proto_rawDesc -) - -func file_github_com_containerd_containerd_api_types_task_task_proto_rawDescGZIP() []byte { - file_github_com_containerd_containerd_api_types_task_task_proto_rawDescOnce.Do(func() { - file_github_com_containerd_containerd_api_types_task_task_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_containerd_api_types_task_task_proto_rawDescData) - }) - return file_github_com_containerd_containerd_api_types_task_task_proto_rawDescData -} - -var file_github_com_containerd_containerd_api_types_task_task_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_github_com_containerd_containerd_api_types_task_task_proto_goTypes = []interface{}{ - (Status)(0), // 0: containerd.v1.types.Status - (*Process)(nil), // 1: containerd.v1.types.Process - (*ProcessInfo)(nil), // 2: containerd.v1.types.ProcessInfo - (*timestamppb.Timestamp)(nil), // 3: google.protobuf.Timestamp - (*anypb.Any)(nil), // 4: google.protobuf.Any -} -var file_github_com_containerd_containerd_api_types_task_task_proto_depIdxs = []int32{ - 0, // 0: containerd.v1.types.Process.status:type_name -> containerd.v1.types.Status - 3, // 1: containerd.v1.types.Process.exited_at:type_name -> google.protobuf.Timestamp - 4, // 2: containerd.v1.types.ProcessInfo.info:type_name -> google.protobuf.Any - 3, // [3:3] is the sub-list for method output_type - 3, // [3:3] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_containerd_api_types_task_task_proto_init() } -func file_github_com_containerd_containerd_api_types_task_task_proto_init() { - if File_github_com_containerd_containerd_api_types_task_task_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Process); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ProcessInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_containerd_api_types_task_task_proto_rawDesc, - NumEnums: 1, - NumMessages: 2, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_containerd_api_types_task_task_proto_goTypes, - DependencyIndexes: file_github_com_containerd_containerd_api_types_task_task_proto_depIdxs, - EnumInfos: file_github_com_containerd_containerd_api_types_task_task_proto_enumTypes, - MessageInfos: file_github_com_containerd_containerd_api_types_task_task_proto_msgTypes, - }.Build() - File_github_com_containerd_containerd_api_types_task_task_proto = out.File - file_github_com_containerd_containerd_api_types_task_task_proto_rawDesc = nil - file_github_com_containerd_containerd_api_types_task_task_proto_goTypes = nil - file_github_com_containerd_containerd_api_types_task_task_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/containerd/api/types/task/task.proto b/vendor/github.com/containerd/containerd/api/types/task/task.proto deleted file mode 100644 index afc8e94bb..000000000 --- a/vendor/github.com/containerd/containerd/api/types/task/task.proto +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -syntax = "proto3"; - -package containerd.v1.types; - -import "google/protobuf/timestamp.proto"; -import "google/protobuf/any.proto"; - -option go_package = "github.com/containerd/containerd/api/types/task"; - -enum Status { - UNKNOWN = 0; - CREATED = 1; - RUNNING = 2; - STOPPED = 3; - PAUSED = 4; - PAUSING = 5; -} - -message Process { - string container_id = 1; - string id = 2; - uint32 pid = 3; - Status status = 4; - string stdin = 5; - string stdout = 6; - string stderr = 7; - bool terminal = 8; - uint32 exit_status = 9; - google.protobuf.Timestamp exited_at = 10; -} - -message ProcessInfo { - // PID is the process ID. - uint32 pid = 1; - // Info contains additional process information. - // - // Info varies by platform. - google.protobuf.Any info = 2; -} diff --git a/vendor/github.com/containerd/errdefs/LICENSE b/vendor/github.com/containerd/errdefs/LICENSE deleted file mode 100644 index 584149b6e..000000000 --- a/vendor/github.com/containerd/errdefs/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://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. diff --git a/vendor/github.com/containerd/errdefs/README.md b/vendor/github.com/containerd/errdefs/README.md deleted file mode 100644 index bd418c63f..000000000 --- a/vendor/github.com/containerd/errdefs/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# errdefs - -A Go package for defining and checking common containerd errors. - -## Project details - -**errdefs** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). -As a containerd sub-project, you will find the: - * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) - -information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/errdefs/errors.go b/vendor/github.com/containerd/errdefs/errors.go deleted file mode 100644 index f654d1964..000000000 --- a/vendor/github.com/containerd/errdefs/errors.go +++ /dev/null @@ -1,443 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// Package errdefs defines the common errors used throughout containerd -// packages. -// -// Use with fmt.Errorf to add context to an error. -// -// To detect an error class, use the IsXXX functions to tell whether an error -// is of a certain type. -package errdefs - -import ( - "context" - "errors" -) - -// Definitions of common error types used throughout containerd. All containerd -// errors returned by most packages will map into one of these errors classes. -// Packages should return errors of these types when they want to instruct a -// client to take a particular action. -// -// These errors map closely to grpc errors. -var ( - ErrUnknown = errUnknown{} - ErrInvalidArgument = errInvalidArgument{} - ErrNotFound = errNotFound{} - ErrAlreadyExists = errAlreadyExists{} - ErrPermissionDenied = errPermissionDenied{} - ErrResourceExhausted = errResourceExhausted{} - ErrFailedPrecondition = errFailedPrecondition{} - ErrConflict = errConflict{} - ErrNotModified = errNotModified{} - ErrAborted = errAborted{} - ErrOutOfRange = errOutOfRange{} - ErrNotImplemented = errNotImplemented{} - ErrInternal = errInternal{} - ErrUnavailable = errUnavailable{} - ErrDataLoss = errDataLoss{} - ErrUnauthenticated = errUnauthorized{} -) - -// cancelled maps to Moby's "ErrCancelled" -type cancelled interface { - Cancelled() -} - -// IsCanceled returns true if the error is due to `context.Canceled`. -func IsCanceled(err error) bool { - return errors.Is(err, context.Canceled) || isInterface[cancelled](err) -} - -type errUnknown struct{} - -func (errUnknown) Error() string { return "unknown" } - -func (errUnknown) Unknown() {} - -func (e errUnknown) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// unknown maps to Moby's "ErrUnknown" -type unknown interface { - Unknown() -} - -// IsUnknown returns true if the error is due to an unknown error, -// unhandled condition or unexpected response. -func IsUnknown(err error) bool { - return errors.Is(err, errUnknown{}) || isInterface[unknown](err) -} - -type errInvalidArgument struct{} - -func (errInvalidArgument) Error() string { return "invalid argument" } - -func (errInvalidArgument) InvalidParameter() {} - -func (e errInvalidArgument) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// invalidParameter maps to Moby's "ErrInvalidParameter" -type invalidParameter interface { - InvalidParameter() -} - -// IsInvalidArgument returns true if the error is due to an invalid argument -func IsInvalidArgument(err error) bool { - return errors.Is(err, ErrInvalidArgument) || isInterface[invalidParameter](err) -} - -// deadlineExceed maps to Moby's "ErrDeadline" -type deadlineExceeded interface { - DeadlineExceeded() -} - -// IsDeadlineExceeded returns true if the error is due to -// `context.DeadlineExceeded`. -func IsDeadlineExceeded(err error) bool { - return errors.Is(err, context.DeadlineExceeded) || isInterface[deadlineExceeded](err) -} - -type errNotFound struct{} - -func (errNotFound) Error() string { return "not found" } - -func (errNotFound) NotFound() {} - -func (e errNotFound) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// notFound maps to Moby's "ErrNotFound" -type notFound interface { - NotFound() -} - -// IsNotFound returns true if the error is due to a missing object -func IsNotFound(err error) bool { - return errors.Is(err, ErrNotFound) || isInterface[notFound](err) -} - -type errAlreadyExists struct{} - -func (errAlreadyExists) Error() string { return "already exists" } - -func (errAlreadyExists) AlreadyExists() {} - -func (e errAlreadyExists) WithMessage(msg string) error { - return customMessage{e, msg} -} - -type alreadyExists interface { - AlreadyExists() -} - -// IsAlreadyExists returns true if the error is due to an already existing -// metadata item -func IsAlreadyExists(err error) bool { - return errors.Is(err, ErrAlreadyExists) || isInterface[alreadyExists](err) -} - -type errPermissionDenied struct{} - -func (errPermissionDenied) Error() string { return "permission denied" } - -func (errPermissionDenied) Forbidden() {} - -func (e errPermissionDenied) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// forbidden maps to Moby's "ErrForbidden" -type forbidden interface { - Forbidden() -} - -// IsPermissionDenied returns true if the error is due to permission denied -// or forbidden (403) response -func IsPermissionDenied(err error) bool { - return errors.Is(err, ErrPermissionDenied) || isInterface[forbidden](err) -} - -type errResourceExhausted struct{} - -func (errResourceExhausted) Error() string { return "resource exhausted" } - -func (errResourceExhausted) ResourceExhausted() {} - -func (e errResourceExhausted) WithMessage(msg string) error { - return customMessage{e, msg} -} - -type resourceExhausted interface { - ResourceExhausted() -} - -// IsResourceExhausted returns true if the error is due to -// a lack of resources or too many attempts. -func IsResourceExhausted(err error) bool { - return errors.Is(err, errResourceExhausted{}) || isInterface[resourceExhausted](err) -} - -type errFailedPrecondition struct{} - -func (e errFailedPrecondition) Error() string { return "failed precondition" } - -func (errFailedPrecondition) FailedPrecondition() {} - -func (e errFailedPrecondition) WithMessage(msg string) error { - return customMessage{e, msg} -} - -type failedPrecondition interface { - FailedPrecondition() -} - -// IsFailedPrecondition returns true if an operation could not proceed due to -// the lack of a particular condition -func IsFailedPrecondition(err error) bool { - return errors.Is(err, errFailedPrecondition{}) || isInterface[failedPrecondition](err) -} - -type errConflict struct{} - -func (errConflict) Error() string { return "conflict" } - -func (errConflict) Conflict() {} - -func (e errConflict) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// conflict maps to Moby's "ErrConflict" -type conflict interface { - Conflict() -} - -// IsConflict returns true if an operation could not proceed due to -// a conflict. -func IsConflict(err error) bool { - return errors.Is(err, errConflict{}) || isInterface[conflict](err) -} - -type errNotModified struct{} - -func (errNotModified) Error() string { return "not modified" } - -func (errNotModified) NotModified() {} - -func (e errNotModified) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// notModified maps to Moby's "ErrNotModified" -type notModified interface { - NotModified() -} - -// IsNotModified returns true if an operation could not proceed due -// to an object not modified from a previous state. -func IsNotModified(err error) bool { - return errors.Is(err, errNotModified{}) || isInterface[notModified](err) -} - -type errAborted struct{} - -func (errAborted) Error() string { return "aborted" } - -func (errAborted) Aborted() {} - -func (e errAborted) WithMessage(msg string) error { - return customMessage{e, msg} -} - -type aborted interface { - Aborted() -} - -// IsAborted returns true if an operation was aborted. -func IsAborted(err error) bool { - return errors.Is(err, errAborted{}) || isInterface[aborted](err) -} - -type errOutOfRange struct{} - -func (errOutOfRange) Error() string { return "out of range" } - -func (errOutOfRange) OutOfRange() {} - -func (e errOutOfRange) WithMessage(msg string) error { - return customMessage{e, msg} -} - -type outOfRange interface { - OutOfRange() -} - -// IsOutOfRange returns true if an operation could not proceed due -// to data being out of the expected range. -func IsOutOfRange(err error) bool { - return errors.Is(err, errOutOfRange{}) || isInterface[outOfRange](err) -} - -type errNotImplemented struct{} - -func (errNotImplemented) Error() string { return "not implemented" } - -func (errNotImplemented) NotImplemented() {} - -func (e errNotImplemented) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// notImplemented maps to Moby's "ErrNotImplemented" -type notImplemented interface { - NotImplemented() -} - -// IsNotImplemented returns true if the error is due to not being implemented -func IsNotImplemented(err error) bool { - return errors.Is(err, errNotImplemented{}) || isInterface[notImplemented](err) -} - -type errInternal struct{} - -func (errInternal) Error() string { return "internal" } - -func (errInternal) System() {} - -func (e errInternal) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// system maps to Moby's "ErrSystem" -type system interface { - System() -} - -// IsInternal returns true if the error returns to an internal or system error -func IsInternal(err error) bool { - return errors.Is(err, errInternal{}) || isInterface[system](err) -} - -type errUnavailable struct{} - -func (errUnavailable) Error() string { return "unavailable" } - -func (errUnavailable) Unavailable() {} - -func (e errUnavailable) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// unavailable maps to Moby's "ErrUnavailable" -type unavailable interface { - Unavailable() -} - -// IsUnavailable returns true if the error is due to a resource being unavailable -func IsUnavailable(err error) bool { - return errors.Is(err, errUnavailable{}) || isInterface[unavailable](err) -} - -type errDataLoss struct{} - -func (errDataLoss) Error() string { return "data loss" } - -func (errDataLoss) DataLoss() {} - -func (e errDataLoss) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// dataLoss maps to Moby's "ErrDataLoss" -type dataLoss interface { - DataLoss() -} - -// IsDataLoss returns true if data during an operation was lost or corrupted -func IsDataLoss(err error) bool { - return errors.Is(err, errDataLoss{}) || isInterface[dataLoss](err) -} - -type errUnauthorized struct{} - -func (errUnauthorized) Error() string { return "unauthorized" } - -func (errUnauthorized) Unauthorized() {} - -func (e errUnauthorized) WithMessage(msg string) error { - return customMessage{e, msg} -} - -// unauthorized maps to Moby's "ErrUnauthorized" -type unauthorized interface { - Unauthorized() -} - -// IsUnauthorized returns true if the error indicates that the user was -// unauthenticated or unauthorized. -func IsUnauthorized(err error) bool { - return errors.Is(err, errUnauthorized{}) || isInterface[unauthorized](err) -} - -func isInterface[T any](err error) bool { - for { - switch x := err.(type) { - case T: - return true - case customMessage: - err = x.err - case interface{ Unwrap() error }: - err = x.Unwrap() - if err == nil { - return false - } - case interface{ Unwrap() []error }: - for _, err := range x.Unwrap() { - if isInterface[T](err) { - return true - } - } - return false - default: - return false - } - } -} - -// customMessage is used to provide a defined error with a custom message. -// The message is not wrapped but can be compared by the `Is(error) bool` interface. -type customMessage struct { - err error - msg string -} - -func (c customMessage) Is(err error) bool { - return c.err == err -} - -func (c customMessage) As(target any) bool { - return errors.As(c.err, target) -} - -func (c customMessage) Error() string { - return c.msg -} diff --git a/vendor/github.com/containerd/errdefs/pkg/LICENSE b/vendor/github.com/containerd/errdefs/pkg/LICENSE deleted file mode 100644 index 584149b6e..000000000 --- a/vendor/github.com/containerd/errdefs/pkg/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://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. diff --git a/vendor/github.com/containerd/errdefs/pkg/errgrpc/grpc.go b/vendor/github.com/containerd/errdefs/pkg/errgrpc/grpc.go deleted file mode 100644 index 59577595a..000000000 --- a/vendor/github.com/containerd/errdefs/pkg/errgrpc/grpc.go +++ /dev/null @@ -1,353 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// Package errgrpc provides utility functions for translating errors to -// and from a gRPC context. -// -// The functions ToGRPC and ToNative can be used to map server-side and -// client-side errors to the correct types. -package errgrpc - -import ( - "context" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - - spb "google.golang.org/genproto/googleapis/rpc/status" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/protoadapt" - "google.golang.org/protobuf/types/known/anypb" - - "github.com/containerd/typeurl/v2" - - "github.com/containerd/errdefs" - "github.com/containerd/errdefs/pkg/internal/cause" - "github.com/containerd/errdefs/pkg/internal/types" -) - -// ToGRPC will attempt to map the error into a grpc error, from the error types -// defined in the the errdefs package and attempign to preserve the original -// description. Any type which does not resolve to a defined error type will -// be assigned the unknown error code. -// -// Further information may be extracted from certain errors depending on their -// type. The grpc error details will be used to attempt to preserve as much of -// the error structures and types as possible. -// -// Errors which can be marshaled using protobuf or typeurl will be considered -// for including as GRPC error details. -// Additionally, use the following interfaces in errors to preserve custom types: -// -// WrapError(error) error - Used to wrap the previous error -// JoinErrors(...error) error - Used to join all previous errors -// CollapseError() - Used for errors which carry information but -// should not have their error message shown. -func ToGRPC(err error) error { - if err == nil { - return nil - } - - if _, ok := status.FromError(err); ok { - // error has already been mapped to grpc - return err - } - st := statusFromError(err) - if st != nil { - if details := errorDetails(err, false); len(details) > 0 { - if ds, _ := st.WithDetails(details...); ds != nil { - st = ds - } - } - err = st.Err() - } - return err -} - -func statusFromError(err error) *status.Status { - switch errdefs.Resolve(err) { - case errdefs.ErrInvalidArgument: - return status.New(codes.InvalidArgument, err.Error()) - case errdefs.ErrNotFound: - return status.New(codes.NotFound, err.Error()) - case errdefs.ErrAlreadyExists: - return status.New(codes.AlreadyExists, err.Error()) - case errdefs.ErrPermissionDenied: - return status.New(codes.PermissionDenied, err.Error()) - case errdefs.ErrResourceExhausted: - return status.New(codes.ResourceExhausted, err.Error()) - case errdefs.ErrFailedPrecondition, errdefs.ErrConflict, errdefs.ErrNotModified: - return status.New(codes.FailedPrecondition, err.Error()) - case errdefs.ErrAborted: - return status.New(codes.Aborted, err.Error()) - case errdefs.ErrOutOfRange: - return status.New(codes.OutOfRange, err.Error()) - case errdefs.ErrNotImplemented: - return status.New(codes.Unimplemented, err.Error()) - case errdefs.ErrInternal: - return status.New(codes.Internal, err.Error()) - case errdefs.ErrUnavailable: - return status.New(codes.Unavailable, err.Error()) - case errdefs.ErrDataLoss: - return status.New(codes.DataLoss, err.Error()) - case errdefs.ErrUnauthenticated: - return status.New(codes.Unauthenticated, err.Error()) - case context.DeadlineExceeded: - return status.New(codes.DeadlineExceeded, err.Error()) - case context.Canceled: - return status.New(codes.Canceled, err.Error()) - case errdefs.ErrUnknown: - return status.New(codes.Unknown, err.Error()) - } - return nil -} - -// errorDetails returns an array of errors which make up the provided error. -// If firstIncluded is true, then all encodable errors will be used, otherwise -// the first error in an error list will be not be used, to account for the -// the base status error which details are added to via wrap or join. -// -// The errors are ordered in way that they can be applied in order by either -// wrapping or joining the errors to recreate an error with the same structure -// when `WrapError` and `JoinErrors` interfaces are used. -// -// The intent is that when re-applying the errors to create a single error, the -// results of calls to `Error()`, `errors.Is`, `errors.As`, and "%+v" formatting -// is the same as the original error. -func errorDetails(err error, firstIncluded bool) []protoadapt.MessageV1 { - switch uerr := err.(type) { - case interface{ Unwrap() error }: - details := errorDetails(uerr.Unwrap(), firstIncluded) - - // If the type is able to wrap, then include if proto - if _, ok := err.(interface{ WrapError(error) error }); ok { - // Get proto message - if protoErr := toProtoMessage(err); protoErr != nil { - details = append(details, protoErr) - } - } - - return details - case interface{ Unwrap() []error }: - var details []protoadapt.MessageV1 - for i, e := range uerr.Unwrap() { - details = append(details, errorDetails(e, firstIncluded || i > 0)...) - } - - if _, ok := err.(interface{ JoinErrors(...error) error }); ok { - // Get proto message - if protoErr := toProtoMessage(err); protoErr != nil { - details = append(details, protoErr) - } - } - return details - } - - if firstIncluded { - if protoErr := toProtoMessage(err); protoErr != nil { - return []protoadapt.MessageV1{protoErr} - } - if gs, ok := status.FromError(ToGRPC(err)); ok { - return []protoadapt.MessageV1{gs.Proto()} - } - // TODO: Else include unknown extra error type? - } - - return nil -} - -func toProtoMessage(err error) protoadapt.MessageV1 { - // Do not double encode proto messages, otherwise use Any - if pm, ok := err.(protoadapt.MessageV1); ok { - return pm - } - if pm, ok := err.(proto.Message); ok { - return protoadapt.MessageV1Of(pm) - } - - if reflect.TypeOf(err).Kind() == reflect.Ptr { - a, aerr := typeurl.MarshalAny(err) - if aerr == nil { - return &anypb.Any{ - TypeUrl: a.GetTypeUrl(), - Value: a.GetValue(), - } - } - } - return nil -} - -// ToGRPCf maps the error to grpc error codes, assembling the formatting string -// and combining it with the target error string. -// -// This is equivalent to grpc.ToGRPC(fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err)) -func ToGRPCf(err error, format string, args ...interface{}) error { - return ToGRPC(fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err)) -} - -// ToNative returns the underlying error from a grpc service based on the grpc -// error code. The grpc details are used to add wrap the error in more context -// or support multiple errors. -func ToNative(err error) error { - if err == nil { - return nil - } - - s, isGRPC := status.FromError(err) - - var ( - desc string - code codes.Code - ) - - if isGRPC { - desc = s.Message() - code = s.Code() - } else { - desc = err.Error() - code = codes.Unknown - } - - var cls error // divide these into error classes, becomes the cause - - switch code { - case codes.InvalidArgument: - cls = errdefs.ErrInvalidArgument - case codes.AlreadyExists: - cls = errdefs.ErrAlreadyExists - case codes.NotFound: - cls = errdefs.ErrNotFound - case codes.Unavailable: - cls = errdefs.ErrUnavailable - case codes.FailedPrecondition: - // TODO: Has suffix is not sufficient for conflict and not modified - // Message should start with ": " or be at beginning of a line - // Message should end with ": " or be at the end of a line - // Compile a regex - if desc == errdefs.ErrConflict.Error() || strings.HasSuffix(desc, ": "+errdefs.ErrConflict.Error()) { - cls = errdefs.ErrConflict - } else if desc == errdefs.ErrNotModified.Error() || strings.HasSuffix(desc, ": "+errdefs.ErrNotModified.Error()) { - cls = errdefs.ErrNotModified - } else { - cls = errdefs.ErrFailedPrecondition - } - case codes.Unimplemented: - cls = errdefs.ErrNotImplemented - case codes.Canceled: - cls = context.Canceled - case codes.DeadlineExceeded: - cls = context.DeadlineExceeded - case codes.Aborted: - cls = errdefs.ErrAborted - case codes.Unauthenticated: - cls = errdefs.ErrUnauthenticated - case codes.PermissionDenied: - cls = errdefs.ErrPermissionDenied - case codes.Internal: - cls = errdefs.ErrInternal - case codes.DataLoss: - cls = errdefs.ErrDataLoss - case codes.OutOfRange: - cls = errdefs.ErrOutOfRange - case codes.ResourceExhausted: - cls = errdefs.ErrResourceExhausted - default: - if idx := strings.LastIndex(desc, cause.UnexpectedStatusPrefix); idx > 0 { - if status, uerr := strconv.Atoi(desc[idx+len(cause.UnexpectedStatusPrefix):]); uerr == nil && status >= 200 && status < 600 { - cls = cause.ErrUnexpectedStatus{Status: status} - } - } - if cls == nil { - cls = errdefs.ErrUnknown - } - } - - msg := rebaseMessage(cls, desc) - if msg == "" { - err = cls - } else if msg != desc { - err = fmt.Errorf("%s: %w", msg, cls) - } else if wm, ok := cls.(interface{ WithMessage(string) error }); ok { - err = wm.WithMessage(msg) - } else { - err = fmt.Errorf("%s: %w", msg, cls) - } - - if isGRPC { - errs := []error{err} - for _, a := range s.Details() { - var derr error - - // First decode error if needed - if s, ok := a.(*spb.Status); ok { - derr = ToNative(status.ErrorProto(s)) - } else if e, ok := a.(error); ok { - derr = e - } else if dany, ok := a.(typeurl.Any); ok { - i, uerr := typeurl.UnmarshalAny(dany) - if uerr == nil { - if e, ok = i.(error); ok { - derr = e - } else { - derr = fmt.Errorf("non-error unmarshalled detail: %v", i) - } - } else { - derr = fmt.Errorf("error of type %q with failure to unmarshal: %v", dany.GetTypeUrl(), uerr) - } - } else { - derr = fmt.Errorf("non-error detail: %v", a) - } - - switch werr := derr.(type) { - case interface{ WrapError(error) error }: - errs[len(errs)-1] = werr.WrapError(errs[len(errs)-1]) - case interface{ JoinErrors(...error) error }: - // TODO: Consider whether this should support joining a subset - errs[0] = werr.JoinErrors(errs...) - case interface{ CollapseError() }: - errs[len(errs)-1] = types.CollapsedError(errs[len(errs)-1], derr) - default: - errs = append(errs, derr) - } - - } - if len(errs) > 1 { - err = errors.Join(errs...) - } else { - err = errs[0] - } - } - - return err -} - -// rebaseMessage removes the repeats for an error at the end of an error -// string. This will happen when taking an error over grpc then remapping it. -// -// Effectively, we just remove the string of cls from the end of err if it -// appears there. -func rebaseMessage(cls error, desc string) string { - clss := cls.Error() - if desc == clss { - return "" - } - - return strings.TrimSuffix(desc, ": "+clss) -} diff --git a/vendor/github.com/containerd/errdefs/pkg/internal/cause/cause.go b/vendor/github.com/containerd/errdefs/pkg/internal/cause/cause.go deleted file mode 100644 index d88756bb0..000000000 --- a/vendor/github.com/containerd/errdefs/pkg/internal/cause/cause.go +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// Package cause is used to define root causes for errors -// common to errors packages like grpc and http. -package cause - -import "fmt" - -type ErrUnexpectedStatus struct { - Status int -} - -const UnexpectedStatusPrefix = "unexpected status " - -func (e ErrUnexpectedStatus) Error() string { - return fmt.Sprintf("%s%d", UnexpectedStatusPrefix, e.Status) -} - -func (ErrUnexpectedStatus) Unknown() {} diff --git a/vendor/github.com/containerd/errdefs/pkg/internal/types/collapsible.go b/vendor/github.com/containerd/errdefs/pkg/internal/types/collapsible.go deleted file mode 100644 index a37e7722a..000000000 --- a/vendor/github.com/containerd/errdefs/pkg/internal/types/collapsible.go +++ /dev/null @@ -1,57 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package types - -import "fmt" - -// CollapsibleError indicates the error should be collapsed -type CollapsibleError interface { - CollapseError() -} - -// CollapsedError returns a new error with the collapsed -// error returned on unwrapped or when formatted with "%+v" -func CollapsedError(err error, collapsed ...error) error { - return collapsedError{err, collapsed} -} - -type collapsedError struct { - error - collapsed []error -} - -func (c collapsedError) Unwrap() []error { - return append([]error{c.error}, c.collapsed...) -} - -func (c collapsedError) Format(s fmt.State, verb rune) { - switch verb { - case 'v': - if s.Flag('+') { - fmt.Fprintf(s, "%+v", c.error) - for _, err := range c.collapsed { - fmt.Fprintf(s, "\n%+v", err) - } - return - } - fallthrough - case 's': - fmt.Fprint(s, c.Error()) - case 'q': - fmt.Fprintf(s, "%q", c.Error()) - } -} diff --git a/vendor/github.com/containerd/errdefs/resolve.go b/vendor/github.com/containerd/errdefs/resolve.go deleted file mode 100644 index c02d4a73f..000000000 --- a/vendor/github.com/containerd/errdefs/resolve.go +++ /dev/null @@ -1,147 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package errdefs - -import "context" - -// Resolve returns the first error found in the error chain which matches an -// error defined in this package or context error. A raw, unwrapped error is -// returned or ErrUnknown if no matching error is found. -// -// This is useful for determining a response code based on the outermost wrapped -// error rather than the original cause. For example, a not found error deep -// in the code may be wrapped as an invalid argument. When determining status -// code from Is* functions, the depth or ordering of the error is not -// considered. -// -// The search order is depth first, a wrapped error returned from any part of -// the chain from `Unwrap() error` will be returned before any joined errors -// as returned by `Unwrap() []error`. -func Resolve(err error) error { - if err == nil { - return nil - } - err = firstError(err) - if err == nil { - err = ErrUnknown - } - return err -} - -func firstError(err error) error { - for { - switch err { - case ErrUnknown, - ErrInvalidArgument, - ErrNotFound, - ErrAlreadyExists, - ErrPermissionDenied, - ErrResourceExhausted, - ErrFailedPrecondition, - ErrConflict, - ErrNotModified, - ErrAborted, - ErrOutOfRange, - ErrNotImplemented, - ErrInternal, - ErrUnavailable, - ErrDataLoss, - ErrUnauthenticated, - context.DeadlineExceeded, - context.Canceled: - return err - } - switch e := err.(type) { - case customMessage: - err = e.err - case unknown: - return ErrUnknown - case invalidParameter: - return ErrInvalidArgument - case notFound: - return ErrNotFound - case alreadyExists: - return ErrAlreadyExists - case forbidden: - return ErrPermissionDenied - case resourceExhausted: - return ErrResourceExhausted - case failedPrecondition: - return ErrFailedPrecondition - case conflict: - return ErrConflict - case notModified: - return ErrNotModified - case aborted: - return ErrAborted - case errOutOfRange: - return ErrOutOfRange - case notImplemented: - return ErrNotImplemented - case system: - return ErrInternal - case unavailable: - return ErrUnavailable - case dataLoss: - return ErrDataLoss - case unauthorized: - return ErrUnauthenticated - case deadlineExceeded: - return context.DeadlineExceeded - case cancelled: - return context.Canceled - case interface{ Unwrap() error }: - err = e.Unwrap() - if err == nil { - return nil - } - case interface{ Unwrap() []error }: - for _, ue := range e.Unwrap() { - if fe := firstError(ue); fe != nil { - return fe - } - } - return nil - case interface{ Is(error) bool }: - for _, target := range []error{ErrUnknown, - ErrInvalidArgument, - ErrNotFound, - ErrAlreadyExists, - ErrPermissionDenied, - ErrResourceExhausted, - ErrFailedPrecondition, - ErrConflict, - ErrNotModified, - ErrAborted, - ErrOutOfRange, - ErrNotImplemented, - ErrInternal, - ErrUnavailable, - ErrDataLoss, - ErrUnauthenticated, - context.DeadlineExceeded, - context.Canceled} { - if e.Is(target) { - return target - } - } - return nil - default: - return nil - } - } -} diff --git a/vendor/github.com/containerd/log/.golangci.yml b/vendor/github.com/containerd/log/.golangci.yml deleted file mode 100644 index a695775df..000000000 --- a/vendor/github.com/containerd/log/.golangci.yml +++ /dev/null @@ -1,30 +0,0 @@ -linters: - enable: - - exportloopref # Checks for pointers to enclosing loop variables - - gofmt - - goimports - - gosec - - ineffassign - - misspell - - nolintlint - - revive - - staticcheck - - tenv # Detects using os.Setenv instead of t.Setenv since Go 1.17 - - unconvert - - unused - - vet - - dupword # Checks for duplicate words in the source code - disable: - - errcheck - -run: - timeout: 5m - skip-dirs: - - api - - cluster - - design - - docs - - docs/man - - releases - - reports - - test # e2e scripts diff --git a/vendor/github.com/containerd/log/LICENSE b/vendor/github.com/containerd/log/LICENSE deleted file mode 100644 index 584149b6e..000000000 --- a/vendor/github.com/containerd/log/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://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. diff --git a/vendor/github.com/containerd/log/README.md b/vendor/github.com/containerd/log/README.md deleted file mode 100644 index 00e084988..000000000 --- a/vendor/github.com/containerd/log/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# log - -A Go package providing a common logging interface across containerd repositories and a way for clients to use and configure logging in containerd packages. - -This package is not intended to be used as a standalone logging package outside of the containerd ecosystem and is intended as an interface wrapper around a logging implementation. -In the future this package may be replaced with a common go logging interface. - -## Project details - -**log** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). -As a containerd sub-project, you will find the: - * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) - -information in our [`containerd/project`](https://github.com/containerd/project) repository. - diff --git a/vendor/github.com/containerd/log/context.go b/vendor/github.com/containerd/log/context.go deleted file mode 100644 index 20153066f..000000000 --- a/vendor/github.com/containerd/log/context.go +++ /dev/null @@ -1,182 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// Package log provides types and functions related to logging, passing -// loggers through a context, and attaching context to the logger. -// -// # Transitional types -// -// This package contains various types that are aliases for types in [logrus]. -// These aliases are intended for transitioning away from hard-coding logrus -// as logging implementation. Consumers of this package are encouraged to use -// the type-aliases from this package instead of directly using their logrus -// equivalent. -// -// The intent is to replace these aliases with locally defined types and -// interfaces once all consumers are no longer directly importing logrus -// types. -// -// IMPORTANT: due to the transitional purpose of this package, it is not -// guaranteed for the full logrus API to be provided in the future. As -// outlined, these aliases are provided as a step to transition away from -// a specific implementation which, as a result, exposes the full logrus API. -// While no decisions have been made on the ultimate design and interface -// provided by this package, we do not expect carrying "less common" features. -package log - -import ( - "context" - "fmt" - - "github.com/sirupsen/logrus" -) - -// G is a shorthand for [GetLogger]. -// -// We may want to define this locally to a package to get package tagged log -// messages. -var G = GetLogger - -// L is an alias for the standard logger. -var L = &Entry{ - Logger: logrus.StandardLogger(), - // Default is three fields plus a little extra room. - Data: make(Fields, 6), -} - -type loggerKey struct{} - -// Fields type to pass to "WithFields". -type Fields = map[string]any - -// Entry is a logging entry. It contains all the fields passed with -// [Entry.WithFields]. It's finally logged when Trace, Debug, Info, Warn, -// Error, Fatal or Panic is called on it. These objects can be reused and -// passed around as much as you wish to avoid field duplication. -// -// Entry is a transitional type, and currently an alias for [logrus.Entry]. -type Entry = logrus.Entry - -// RFC3339NanoFixed is [time.RFC3339Nano] with nanoseconds padded using -// zeros to ensure the formatted time is always the same number of -// characters. -const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" - -// Level is a logging level. -type Level = logrus.Level - -// Supported log levels. -const ( - // TraceLevel level. Designates finer-grained informational events - // than [DebugLevel]. - TraceLevel Level = logrus.TraceLevel - - // DebugLevel level. Usually only enabled when debugging. Very verbose - // logging. - DebugLevel Level = logrus.DebugLevel - - // InfoLevel level. General operational entries about what's going on - // inside the application. - InfoLevel Level = logrus.InfoLevel - - // WarnLevel level. Non-critical entries that deserve eyes. - WarnLevel Level = logrus.WarnLevel - - // ErrorLevel level. Logs errors that should definitely be noted. - // Commonly used for hooks to send errors to an error tracking service. - ErrorLevel Level = logrus.ErrorLevel - - // FatalLevel level. Logs and then calls "logger.Exit(1)". It exits - // even if the logging level is set to Panic. - FatalLevel Level = logrus.FatalLevel - - // PanicLevel level. This is the highest level of severity. Logs and - // then calls panic with the message passed to Debug, Info, ... - PanicLevel Level = logrus.PanicLevel -) - -// SetLevel sets log level globally. It returns an error if the given -// level is not supported. -// -// level can be one of: -// -// - "trace" ([TraceLevel]) -// - "debug" ([DebugLevel]) -// - "info" ([InfoLevel]) -// - "warn" ([WarnLevel]) -// - "error" ([ErrorLevel]) -// - "fatal" ([FatalLevel]) -// - "panic" ([PanicLevel]) -func SetLevel(level string) error { - lvl, err := logrus.ParseLevel(level) - if err != nil { - return err - } - - L.Logger.SetLevel(lvl) - return nil -} - -// GetLevel returns the current log level. -func GetLevel() Level { - return L.Logger.GetLevel() -} - -// OutputFormat specifies a log output format. -type OutputFormat string - -// Supported log output formats. -const ( - // TextFormat represents the text logging format. - TextFormat OutputFormat = "text" - - // JSONFormat represents the JSON logging format. - JSONFormat OutputFormat = "json" -) - -// SetFormat sets the log output format ([TextFormat] or [JSONFormat]). -func SetFormat(format OutputFormat) error { - switch format { - case TextFormat: - L.Logger.SetFormatter(&logrus.TextFormatter{ - TimestampFormat: RFC3339NanoFixed, - FullTimestamp: true, - }) - return nil - case JSONFormat: - L.Logger.SetFormatter(&logrus.JSONFormatter{ - TimestampFormat: RFC3339NanoFixed, - }) - return nil - default: - return fmt.Errorf("unknown log format: %s", format) - } -} - -// WithLogger returns a new context with the provided logger. Use in -// combination with logger.WithField(s) for great effect. -func WithLogger(ctx context.Context, logger *Entry) context.Context { - return context.WithValue(ctx, loggerKey{}, logger.WithContext(ctx)) -} - -// GetLogger retrieves the current logger from the context. If no logger is -// available, the default logger is returned. -func GetLogger(ctx context.Context) *Entry { - if logger := ctx.Value(loggerKey{}); logger != nil { - return logger.(*Entry) - } - return L.WithContext(ctx) -} diff --git a/vendor/github.com/containerd/ttrpc/.gitattributes b/vendor/github.com/containerd/ttrpc/.gitattributes deleted file mode 100644 index d207b1802..000000000 --- a/vendor/github.com/containerd/ttrpc/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -*.go text eol=lf diff --git a/vendor/github.com/containerd/ttrpc/.gitignore b/vendor/github.com/containerd/ttrpc/.gitignore deleted file mode 100644 index 88ceb2764..000000000 --- a/vendor/github.com/containerd/ttrpc/.gitignore +++ /dev/null @@ -1,13 +0,0 @@ -# Binaries for programs and plugins -/bin/ -*.exe -*.dll -*.so -*.dylib - -# Test binary, build with `go test -c` -*.test - -# Output of the go coverage tool, specifically when used with LiteIDE -*.out -coverage.txt diff --git a/vendor/github.com/containerd/ttrpc/.golangci.yml b/vendor/github.com/containerd/ttrpc/.golangci.yml deleted file mode 100644 index 6462e52f6..000000000 --- a/vendor/github.com/containerd/ttrpc/.golangci.yml +++ /dev/null @@ -1,52 +0,0 @@ -linters: - enable: - - staticcheck - - unconvert - - gofmt - - goimports - - revive - - ineffassign - - vet - - unused - - misspell - disable: - - errcheck - -linters-settings: - revive: - ignore-generated-headers: true - rules: - - name: blank-imports - - name: context-as-argument - - name: context-keys-type - - name: dot-imports - - name: error-return - - name: error-strings - - name: error-naming - - name: exported - - name: if-return - - name: increment-decrement - - name: var-naming - arguments: [["UID", "GID"], []] - - name: var-declaration - - name: package-comments - - name: range - - name: receiver-naming - - name: time-naming - - name: unexported-return - - name: indent-error-flow - - name: errorf - - name: empty-block - - name: superfluous-else - - name: unused-parameter - - name: unreachable-code - - name: redefines-builtin-id - -issues: - include: - - EXC0002 - -run: - timeout: 8m - skip-dirs: - - example diff --git a/vendor/github.com/containerd/ttrpc/LICENSE b/vendor/github.com/containerd/ttrpc/LICENSE deleted file mode 100644 index 261eeb9e9..000000000 --- a/vendor/github.com/containerd/ttrpc/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/vendor/github.com/containerd/ttrpc/Makefile b/vendor/github.com/containerd/ttrpc/Makefile deleted file mode 100644 index c3a497dca..000000000 --- a/vendor/github.com/containerd/ttrpc/Makefile +++ /dev/null @@ -1,180 +0,0 @@ -# Copyright The containerd Authors. - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at - -# http://www.apache.org/licenses/LICENSE-2.0 - -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - - -# Go command to use for build -GO ?= go -INSTALL ?= install - -# Root directory of the project (absolute path). -ROOTDIR=$(dir $(abspath $(lastword $(MAKEFILE_LIST)))) - -WHALE = "🇩" -ONI = "👹" - -# Project binaries. -COMMANDS=protoc-gen-go-ttrpc protoc-gen-gogottrpc - -ifdef BUILDTAGS - GO_BUILDTAGS = ${BUILDTAGS} -endif -GO_BUILDTAGS ?= -GO_TAGS=$(if $(GO_BUILDTAGS),-tags "$(strip $(GO_BUILDTAGS))",) - -# Project packages. -PACKAGES=$(shell $(GO) list ${GO_TAGS} ./... | grep -v /example) -TESTPACKAGES=$(shell $(GO) list ${GO_TAGS} ./... | grep -v /cmd | grep -v /integration | grep -v /example) -BINPACKAGES=$(addprefix ./cmd/,$(COMMANDS)) - -#Replaces ":" (*nix), ";" (windows) with newline for easy parsing -GOPATHS=$(shell echo ${GOPATH} | tr ":" "\n" | tr ";" "\n") - -TESTFLAGS_RACE= -GO_BUILD_FLAGS= -# See Golang issue re: '-trimpath': https://github.com/golang/go/issues/13809 -GO_GCFLAGS=$(shell \ - set -- ${GOPATHS}; \ - echo "-gcflags=-trimpath=$${1}/src"; \ - ) - -BINARIES=$(addprefix bin/,$(COMMANDS)) - -# Flags passed to `go test` -TESTFLAGS ?= $(TESTFLAGS_RACE) $(EXTRA_TESTFLAGS) -TESTFLAGS_PARALLEL ?= 8 - -# Use this to replace `go test` with, for instance, `gotestsum` -GOTEST ?= $(GO) test - -.PHONY: clean all AUTHORS build binaries test integration generate protos check-protos coverage ci check help install vendor install-protobuf install-protobuild -.DEFAULT: default - -# Forcibly set the default goal to all, in case an include above brought in a rule definition. -.DEFAULT_GOAL := all - -all: binaries - -check: proto-fmt ## run all linters - @echo "$(WHALE) $@" - GOGC=75 golangci-lint run - -ci: check binaries check-protos coverage # coverage-integration ## to be used by the CI - -AUTHORS: .mailmap .git/HEAD - git log --format='%aN <%aE>' | sort -fu > $@ - -generate: protos - @echo "$(WHALE) $@" - @PATH="${ROOTDIR}/bin:${PATH}" $(GO) generate -x ${PACKAGES} - -protos: bin/protoc-gen-gogottrpc bin/protoc-gen-go-ttrpc ## generate protobuf - @echo "$(WHALE) $@" - @(PATH="${ROOTDIR}/bin:${PATH}" protobuild --quiet ${PACKAGES}) - -check-protos: protos ## check if protobufs needs to be generated again - @echo "$(WHALE) $@" - @test -z "$$(git status --short | grep ".pb.go" | tee /dev/stderr)" || \ - ((git diff | cat) && \ - (echo "$(ONI) please run 'make protos' when making changes to proto files" && false)) - -check-api-descriptors: protos ## check that protobuf changes aren't present. - @echo "$(WHALE) $@" - @test -z "$$(git status --short | grep ".pb.txt" | tee /dev/stderr)" || \ - ((git diff $$(find . -name '*.pb.txt') | cat) && \ - (echo "$(ONI) please run 'make protos' when making changes to proto files and check-in the generated descriptor file changes" && false)) - -proto-fmt: ## check format of proto files - @echo "$(WHALE) $@" - @test -z "$$(find . -name '*.proto' -type f -exec grep -Hn -e "^ " {} \; | tee /dev/stderr)" || \ - (echo "$(ONI) please indent proto files with tabs only" && false) - @test -z "$$(find . -name '*.proto' -type f -exec grep -Hn "Meta meta = " {} \; | grep -v '(gogoproto.nullable) = false' | tee /dev/stderr)" || \ - (echo "$(ONI) meta fields in proto files must have option (gogoproto.nullable) = false" && false) - -build: ## build the go packages - @echo "$(WHALE) $@" - @$(GO) build ${DEBUG_GO_GCFLAGS} ${GO_GCFLAGS} ${GO_BUILD_FLAGS} ${EXTRA_FLAGS} ${PACKAGES} - -test: ## run tests, except integration tests and tests that require root - @echo "$(WHALE) $@" - @$(GOTEST) ${TESTFLAGS} ${TESTPACKAGES} - -integration: ## run integration tests - @echo "$(WHALE) $@" - @cd "${ROOTDIR}/integration" && $(GOTEST) -v ${TESTFLAGS} -parallel ${TESTFLAGS_PARALLEL} . - -benchmark: ## run benchmarks tests - @echo "$(WHALE) $@" - @$(GO) test ${TESTFLAGS} -bench . -run Benchmark - -FORCE: - -define BUILD_BINARY -@echo "$(WHALE) $@" -@$(GO) build ${DEBUG_GO_GCFLAGS} ${GO_GCFLAGS} ${GO_BUILD_FLAGS} -o $@ ${GO_TAGS} ./$< -endef - -# Build a binary from a cmd. -bin/%: cmd/% FORCE - $(call BUILD_BINARY) - -binaries: $(BINARIES) ## build binaries - @echo "$(WHALE) $@" - -clean: ## clean up binaries - @echo "$(WHALE) $@" - @rm -f $(BINARIES) - -install: ## install binaries - @echo "$(WHALE) $@ $(BINPACKAGES)" - @$(GO) install $(BINPACKAGES) - -install-protobuf: - @echo "$(WHALE) $@" - @script/install-protobuf - -install-protobuild: - @echo "$(WHALE) $@" - @$(GO) install google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.1 - @$(GO) install github.com/containerd/protobuild@14832ccc41429f5c4f81028e5af08aa233a219cf - -coverage: ## generate coverprofiles from the unit tests, except tests that require root - @echo "$(WHALE) $@" - @rm -f coverage.txt - @$(GO) test ${TESTFLAGS} ${TESTPACKAGES} 2> /dev/null - @( for pkg in ${PACKAGES}; do \ - $(GO) test ${TESTFLAGS} \ - -cover \ - -coverprofile=profile.out \ - -covermode=atomic $$pkg || exit; \ - if [ -f profile.out ]; then \ - cat profile.out >> coverage.txt; \ - rm profile.out; \ - fi; \ - done ) - -vendor: ## ensure all the go.mod/go.sum files are up-to-date - @echo "$(WHALE) $@" - @$(GO) mod tidy - @$(GO) mod verify - -verify-vendor: ## verify if all the go.mod/go.sum files are up-to-date - @echo "$(WHALE) $@" - @$(GO) mod tidy - @$(GO) mod verify - @test -z "$$(git status --short | grep "go.sum" | tee /dev/stderr)" || \ - ((git diff | cat) && \ - (echo "$(ONI) make sure to checkin changes after go mod tidy" && false)) - -help: ## this help - @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) | sort diff --git a/vendor/github.com/containerd/ttrpc/PROTOCOL.md b/vendor/github.com/containerd/ttrpc/PROTOCOL.md deleted file mode 100644 index 12b43f6bd..000000000 --- a/vendor/github.com/containerd/ttrpc/PROTOCOL.md +++ /dev/null @@ -1,240 +0,0 @@ -# Protocol Specification - -The ttrpc protocol is client/server protocol to support multiple request streams -over a single connection with lightweight framing. The client represents the -process which initiated the underlying connection and the server is the process -which accepted the connection. The protocol is currently defined as -asymmetrical, with clients sending requests and servers sending responses. Both -clients and servers are able to send stream data. The roles are also used in -determining the stream identifiers, with client initiated streams using odd -number identifiers and server initiated using even number. The protocol may be -extended in the future to support server initiated streams, that is not -supported in the latest version. - -## Purpose - -The ttrpc protocol is designed to be lightweight and optimized for low latency -and reliable connections between processes on the same host. The protocol does -not include features for handling unreliable connections such as handshakes, -resets, pings, or flow control. The protocol is designed to make low-overhead -implementations as simple as possible. It is not intended as a suitable -replacement for HTTP2/3 over the network. - -## Message Frame - -Each Message Frame consists of a 10-byte message header followed -by message data. The data length and stream ID are both big-endian -4-byte unsigned integers. The message type is an unsigned 1-byte -integer. The flags are also an unsigned 1-byte integer and -use is defined by the message type. - - +---------------------------------------------------------------+ - | Data Length (32) | - +---------------------------------------------------------------+ - | Stream ID (32) | - +---------------+-----------------------------------------------+ - | Msg Type (8) | - +---------------+ - | Flags (8) | - +---------------+-----------------------------------------------+ - | Data (*) | - +---------------------------------------------------------------+ - -The Data Length field represents the number of bytes in the Data field. The -total frame size will always be Data Length + 10 bytes. The maximum data length -is 4MB and any larger size should be rejected. Due to the maximum data size -being less than 16MB, the first frame byte should always be zero. This first -byte should be considered reserved for future use. - -The Stream ID must be odd for client initiated streams and even for server -initiated streams. Server initiated streams are not currently supported. - -## Mesage Types - -| Message Type | Name | Description | -|--------------|----------|----------------------------------| -| 0x01 | Request | Initiates stream | -| 0x02 | Response | Final stream data and terminates | -| 0x03 | Data | Stream data | - -### Request - -The request message is used to initiate stream and send along request data for -properly routing and handling the stream. The stream may indicate unary without -any inbound or outbound stream data with only a response is expected on the -stream. The request may also indicate the stream is still open for more data and -no response is expected until data is finished. If the remote indicates the -stream is closed, the request may be considered non-unary but without anymore -stream data sent. In the case of `remote closed`, the remote still expects to -receive a response or stream data. For compatibility with non streaming clients, -a request with empty flags indicates a unary request. - -#### Request Flags - -| Flag | Name | Description | -|------|-----------------|--------------------------------------------------| -| 0x01 | `remote closed` | Non-unary, but no more data expected from remote | -| 0x02 | `remote open` | Non-unary, remote is still sending data | - -### Response - -The response message is used to end a stream with data, an empty response, or -an error. A response message is the only expected message after a unary request. -A non-unary request does not require a response message if the server is sending -back stream data. A non-unary stream may return a single response message but no -other stream data may follow. - -#### Response Flags - -No response flags are defined at this time, flags should be empty. - -### Data - -The data message is used to send data on an already initialized stream. Either -client or server may send data. A data message is not allowed on a unary stream. -A data message should not be sent after indicating `remote closed` to the peer. -The last data message on a stream must set the `remote closed` flag. - -The `no data` flag is used to indicate that the data message does not include -any data. This is normally used with the `remote closed` flag to indicate the -stream is now closed without transmitting any data. Since ttrpc normally -transmits a single object per message, a zero length data message may be -interpreted as an empty object. For example, transmitting the number zero as a -protobuf message ends up with a data length of zero, but the message is still -considered data and should be processed. - -#### Data Flags - -| Flag | Name | Description | -|------|-----------------|-----------------------------------| -| 0x01 | `remote closed` | No more data expected from remote | -| 0x04 | `no data` | This message does not have data | - -## Streaming - -All ttrpc requests use streams to transfer data. Unary streams will only have -two messages sent per stream, a request from a client and a response from the -server. Non-unary streams, however, may send any numbers of messages from the -client and the server. This makes stream management more complicated than unary -streams since both client and server need to track additional state. To keep -this management as simple as possible, ttrpc minimizes the number of states and -uses two flags instead of control frames. Each stream has two states while a -stream is still alive: `local closed` and `remote closed`. Each peer considers -local and remote from their own perspective and sets flags from the other peer's -perspective. For example, if a client sends a data frame with the -`remote closed` flag, that is indicating that the client is now `local closed` -and the server will be `remote closed`. A unary operation does not need to send -these flags since each received message always indicates `remote closed`. Once a -peer is both `local closed` and `remote closed`, the stream is considered -finished and may be cleaned up. - -Due to the asymmetric nature of the current protocol, a client should -always be in the `local closed` state before `remote closed` and a server should -always be in the `remote closed` state before `local closed`. This happens -because the client is always initiating requests and a client always expects a -final response back from a server to indicate the initiated request has been -fulfilled. This may mean server sends a final empty response to finish a stream -even after it has already completed sending data before the client. - -### Unary State Diagram - - +--------+ +--------+ - | Client | | Server | - +---+----+ +----+---+ - | +---------+ | - local >---------------+ Request +--------------------> remote - closed | +---------+ | closed - | | - | +----------+ | - finished <--------------+ Response +--------------------< finished - | +----------+ | - | | - -### Non-Unary State Diagrams - -RC: `remote closed` flag -RO: `remote open` flag - - +--------+ +--------+ - | Client | | Server | - +---+----+ +----+---+ - | +--------------+ | - >-------------+ Request [RO] +-----------------> - | +--------------+ | - | | - | +------+ | - >-----------------+ Data +---------------------> - | +------+ | - | | - | +-----------+ | - local >---------------+ Data [RC] +------------------> remote - closed | +-----------+ | closed - | | - | +----------+ | - finished <--------------+ Response +--------------------< finished - | +----------+ | - | | - - +--------+ +--------+ - | Client | | Server | - +---+----+ +----+---+ - | +--------------+ | - local >-------------+ Request [RC] +-----------------> remote - closed | +--------------+ | closed - | | - | +------+ | - <-----------------+ Data +---------------------< - | +------+ | - | | - | +-----------+ | - finished <---------------+ Data [RC] +------------------< finished - | +-----------+ | - | | - - +--------+ +--------+ - | Client | | Server | - +---+----+ +----+---+ - | +--------------+ | - >-------------+ Request [RO] +-----------------> - | +--------------+ | - | | - | +------+ | - >-----------------+ Data +---------------------> - | +------+ | - | | - | +------+ | - <-----------------+ Data +---------------------< - | +------+ | - | | - | +------+ | - >-----------------+ Data +---------------------> - | +------+ | - | | - | +-----------+ | - local >---------------+ Data [RC] +------------------> remote - closed | +-----------+ | closed - | | - | +------+ | - <-----------------+ Data +---------------------< - | +------+ | - | | - | +-----------+ | - finished <---------------+ Data [RC] +------------------< finished - | +-----------+ | - | | - -## RPC - -While this protocol is defined primarily to support Remote Procedure Calls, the -protocol does not define the request and response types beyond the messages -defined in the protocol. The implementation provides a default protobuf -definition of request and response which may be used for cross language rpc. -All implementations should at least define a request type which support -routing by procedure name and a response type which supports call status. - -## Version History - -| Version | Features | -|---------|---------------------| -| 1.0 | Unary requests only | -| 1.2 | Streaming support | diff --git a/vendor/github.com/containerd/ttrpc/Protobuild.toml b/vendor/github.com/containerd/ttrpc/Protobuild.toml deleted file mode 100644 index 0f6ccbd1e..000000000 --- a/vendor/github.com/containerd/ttrpc/Protobuild.toml +++ /dev/null @@ -1,28 +0,0 @@ -version = "2" -generators = ["go"] - -# Control protoc include paths. Below are usually some good defaults, but feel -# free to try it without them if it works for your project. -[includes] - # Include paths that will be added before all others. Typically, you want to - # treat the root of the project as an include, but this may not be necessary. - before = ["."] - - # Paths that will be added untouched to the end of the includes. We use - # `/usr/local/include` to pickup the common install location of protobuf. - # This is the default. - after = ["/usr/local/include"] - -# This section maps protobuf imports to Go packages. These will become -# `-M` directives in the call to the go protobuf generator. -[packages] - "google/protobuf/any.proto" = "github.com/gogo/protobuf/types" - "proto/status.proto" = "google.golang.org/genproto/googleapis/rpc/status" - -[[overrides]] -# enable ttrpc and disable fieldpath and grpc for the shim -prefixes = ["github.com/containerd/ttrpc/integration/streaming"] -generators = ["go", "go-ttrpc"] - -[overrides.parameters.go-ttrpc] -prefix = "TTRPC" diff --git a/vendor/github.com/containerd/ttrpc/README.md b/vendor/github.com/containerd/ttrpc/README.md deleted file mode 100644 index ce95f63be..000000000 --- a/vendor/github.com/containerd/ttrpc/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# ttrpc - -[![Build Status](https://github.com/containerd/ttrpc/actions/workflows/ci.yml/badge.svg)](https://github.com/containerd/ttrpc/actions/workflows/ci.yml) - -GRPC for low-memory environments. - -The existing grpc-go project requires a lot of memory overhead for importing -packages and at runtime. While this is great for many services with low density -requirements, this can be a problem when running a large number of services on -a single machine or on a machine with a small amount of memory. - -Using the same GRPC definitions, this project reduces the binary size and -protocol overhead required. We do this by eliding the `net/http`, `net/http2` -and `grpc` package used by grpc replacing it with a lightweight framing -protocol. The result are smaller binaries that use less resident memory with -the same ease of use as GRPC. - -Please note that while this project supports generating either end of the -protocol, the generated service definitions will be incompatible with regular -GRPC services, as they do not speak the same protocol. - -# Protocol - -See the [protocol specification](./PROTOCOL.md). - -# Usage - -Create a gogo vanity binary (see -[`cmd/protoc-gen-gogottrpc/main.go`](cmd/protoc-gen-gogottrpc/main.go) for an -example with the ttrpc plugin enabled. - -It's recommended to use [`protobuild`](https://github.com/containerd/protobuild) -to build the protobufs for this project, but this will work with protoc -directly, if required. - -# Differences from GRPC - -- The protocol stack has been replaced with a lighter protocol that doesn't - require http, http2 and tls. -- The client and server interface are identical whereas in GRPC there is a - client and server interface that are different. -- The Go stdlib context package is used instead. - -# Status - -TODO: - -- [ ] Add testing under concurrent load to ensure -- [ ] Verify connection error handling - -# Project details - -ttrpc is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). -As a containerd sub-project, you will find the: - * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) - -information in our [`containerd/project`](https://github.com/containerd/project) repository. diff --git a/vendor/github.com/containerd/ttrpc/channel.go b/vendor/github.com/containerd/ttrpc/channel.go deleted file mode 100644 index 872261e6d..000000000 --- a/vendor/github.com/containerd/ttrpc/channel.go +++ /dev/null @@ -1,182 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "bufio" - "encoding/binary" - "fmt" - "io" - "net" - "sync" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -const ( - messageHeaderLength = 10 - messageLengthMax = 4 << 20 -) - -type messageType uint8 - -const ( - messageTypeRequest messageType = 0x1 - messageTypeResponse messageType = 0x2 - messageTypeData messageType = 0x3 -) - -func (mt messageType) String() string { - switch mt { - case messageTypeRequest: - return "request" - case messageTypeResponse: - return "response" - case messageTypeData: - return "data" - default: - return "unknown" - } -} - -const ( - flagRemoteClosed uint8 = 0x1 - flagRemoteOpen uint8 = 0x2 - flagNoData uint8 = 0x4 -) - -// messageHeader represents the fixed-length message header of 10 bytes sent -// with every request. -type messageHeader struct { - Length uint32 // length excluding this header. b[:4] - StreamID uint32 // identifies which request stream message is a part of. b[4:8] - Type messageType // message type b[8] - Flags uint8 // type specific flags b[9] -} - -func readMessageHeader(p []byte, r io.Reader) (messageHeader, error) { - _, err := io.ReadFull(r, p[:messageHeaderLength]) - if err != nil { - return messageHeader{}, err - } - - return messageHeader{ - Length: binary.BigEndian.Uint32(p[:4]), - StreamID: binary.BigEndian.Uint32(p[4:8]), - Type: messageType(p[8]), - Flags: p[9], - }, nil -} - -func writeMessageHeader(w io.Writer, p []byte, mh messageHeader) error { - binary.BigEndian.PutUint32(p[:4], mh.Length) - binary.BigEndian.PutUint32(p[4:8], mh.StreamID) - p[8] = byte(mh.Type) - p[9] = mh.Flags - - _, err := w.Write(p[:]) - return err -} - -var buffers sync.Pool - -type channel struct { - conn net.Conn - bw *bufio.Writer - br *bufio.Reader - hrbuf [messageHeaderLength]byte // avoid alloc when reading header - hwbuf [messageHeaderLength]byte -} - -func newChannel(conn net.Conn) *channel { - return &channel{ - conn: conn, - bw: bufio.NewWriter(conn), - br: bufio.NewReader(conn), - } -} - -// recv a message from the channel. The returned buffer contains the message. -// -// If a valid grpc status is returned, the message header -// returned will be valid and caller should send that along to -// the correct consumer. The bytes on the underlying channel -// will be discarded. -func (ch *channel) recv() (messageHeader, []byte, error) { - mh, err := readMessageHeader(ch.hrbuf[:], ch.br) - if err != nil { - return messageHeader{}, nil, err - } - - if mh.Length > uint32(messageLengthMax) { - if _, err := ch.br.Discard(int(mh.Length)); err != nil { - return mh, nil, fmt.Errorf("failed to discard after receiving oversized message: %w", err) - } - - return mh, nil, status.Errorf(codes.ResourceExhausted, "message length %v exceed maximum message size of %v", mh.Length, messageLengthMax) - } - - var p []byte - if mh.Length > 0 { - p = ch.getmbuf(int(mh.Length)) - if _, err := io.ReadFull(ch.br, p); err != nil { - return messageHeader{}, nil, fmt.Errorf("failed reading message: %w", err) - } - } - - return mh, p, nil -} - -func (ch *channel) send(streamID uint32, t messageType, flags uint8, p []byte) error { - if len(p) > messageLengthMax { - return OversizedMessageError(len(p)) - } - - if err := writeMessageHeader(ch.bw, ch.hwbuf[:], messageHeader{Length: uint32(len(p)), StreamID: streamID, Type: t, Flags: flags}); err != nil { - return err - } - - if len(p) > 0 { - _, err := ch.bw.Write(p) - if err != nil { - return err - } - } - - return ch.bw.Flush() -} - -func (ch *channel) getmbuf(size int) []byte { - // we can't use the standard New method on pool because we want to allocate - // based on size. - b, ok := buffers.Get().(*[]byte) - if !ok || cap(*b) < size { - // TODO(stevvooe): It may be better to allocate these in fixed length - // buckets to reduce fragmentation but its not clear that would help - // with performance. An ilogb approach or similar would work well. - bb := make([]byte, size) - b = &bb - } else { - *b = (*b)[:size] - } - return *b -} - -func (ch *channel) putmbuf(p []byte) { - buffers.Put(&p) -} diff --git a/vendor/github.com/containerd/ttrpc/client.go b/vendor/github.com/containerd/ttrpc/client.go deleted file mode 100644 index b1bc7a3fc..000000000 --- a/vendor/github.com/containerd/ttrpc/client.go +++ /dev/null @@ -1,570 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "errors" - "fmt" - "io" - "net" - "strings" - "sync" - "syscall" - "time" - - "github.com/containerd/log" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" -) - -// Client for a ttrpc server -type Client struct { - codec codec - conn net.Conn - channel *channel - - streamLock sync.RWMutex - streams map[streamID]*stream - nextStreamID streamID - sendLock sync.Mutex - - ctx context.Context - closed func() - - closeOnce sync.Once - userCloseFunc func() - userCloseWaitCh chan struct{} - - interceptor UnaryClientInterceptor -} - -// ClientOpts configures a client -type ClientOpts func(c *Client) - -// WithOnClose sets the close func whenever the client's Close() method is called -func WithOnClose(onClose func()) ClientOpts { - return func(c *Client) { - c.userCloseFunc = onClose - } -} - -// WithUnaryClientInterceptor sets the provided client interceptor -func WithUnaryClientInterceptor(i UnaryClientInterceptor) ClientOpts { - return func(c *Client) { - c.interceptor = i - } -} - -// WithChainUnaryClientInterceptor sets the provided chain of client interceptors -func WithChainUnaryClientInterceptor(interceptors ...UnaryClientInterceptor) ClientOpts { - return func(c *Client) { - if len(interceptors) == 0 { - return - } - if c.interceptor != nil { - interceptors = append([]UnaryClientInterceptor{c.interceptor}, interceptors...) - } - c.interceptor = func( - ctx context.Context, - req *Request, - reply *Response, - info *UnaryClientInfo, - final Invoker, - ) error { - return interceptors[0](ctx, req, reply, info, - chainUnaryInterceptors(interceptors[1:], final, info)) - } - } -} - -func chainUnaryInterceptors(interceptors []UnaryClientInterceptor, final Invoker, info *UnaryClientInfo) Invoker { - if len(interceptors) == 0 { - return final - } - return func( - ctx context.Context, - req *Request, - reply *Response, - ) error { - return interceptors[0](ctx, req, reply, info, - chainUnaryInterceptors(interceptors[1:], final, info)) - } -} - -// NewClient creates a new ttrpc client using the given connection -func NewClient(conn net.Conn, opts ...ClientOpts) *Client { - ctx, cancel := context.WithCancel(context.Background()) - channel := newChannel(conn) - c := &Client{ - codec: codec{}, - conn: conn, - channel: channel, - streams: make(map[streamID]*stream), - nextStreamID: 1, - closed: cancel, - ctx: ctx, - userCloseFunc: func() {}, - userCloseWaitCh: make(chan struct{}), - } - - for _, o := range opts { - o(c) - } - - if c.interceptor == nil { - c.interceptor = defaultClientInterceptor - } - - go c.run() - return c -} - -func (c *Client) send(sid uint32, mt messageType, flags uint8, b []byte) error { - c.sendLock.Lock() - defer c.sendLock.Unlock() - return c.channel.send(sid, mt, flags, b) -} - -// Call makes a unary request and returns with response -func (c *Client) Call(ctx context.Context, service, method string, req, resp interface{}) error { - payload, err := c.codec.Marshal(req) - if err != nil { - return err - } - - var ( - creq = &Request{ - Service: service, - Method: method, - Payload: payload, - // TODO: metadata from context - } - - cresp = &Response{} - ) - - if metadata, ok := GetMetadata(ctx); ok { - metadata.setRequest(creq) - } - - if dl, ok := ctx.Deadline(); ok { - creq.TimeoutNano = time.Until(dl).Nanoseconds() - } - - info := &UnaryClientInfo{ - FullMethod: fullPath(service, method), - } - if err := c.interceptor(ctx, creq, cresp, info, c.dispatch); err != nil { - return err - } - - if err := c.codec.Unmarshal(cresp.Payload, resp); err != nil { - return err - } - - if cresp.Status != nil && cresp.Status.Code != int32(codes.OK) { - return status.ErrorProto(cresp.Status) - } - return nil -} - -// StreamDesc describes the stream properties, whether the stream has -// a streaming client, a streaming server, or both -type StreamDesc struct { - StreamingClient bool - StreamingServer bool -} - -// ClientStream is used to send or recv messages on the underlying stream -type ClientStream interface { - CloseSend() error - SendMsg(m interface{}) error - RecvMsg(m interface{}) error -} - -type clientStream struct { - ctx context.Context - s *stream - c *Client - desc *StreamDesc - localClosed bool - remoteClosed bool -} - -func (cs *clientStream) CloseSend() error { - if !cs.desc.StreamingClient { - return fmt.Errorf("%w: cannot close non-streaming client", ErrProtocol) - } - if cs.localClosed { - return ErrStreamClosed - } - err := cs.s.send(messageTypeData, flagRemoteClosed|flagNoData, nil) - if err != nil { - return filterCloseErr(err) - } - cs.localClosed = true - return nil -} - -func (cs *clientStream) SendMsg(m interface{}) error { - if !cs.desc.StreamingClient { - return fmt.Errorf("%w: cannot send data from non-streaming client", ErrProtocol) - } - if cs.localClosed { - return ErrStreamClosed - } - - var ( - payload []byte - err error - ) - if m != nil { - payload, err = cs.c.codec.Marshal(m) - if err != nil { - return err - } - } - - err = cs.s.send(messageTypeData, 0, payload) - if err != nil { - return filterCloseErr(err) - } - - return nil -} - -func (cs *clientStream) RecvMsg(m interface{}) error { - if cs.remoteClosed { - return io.EOF - } - - var msg *streamMessage - select { - case <-cs.ctx.Done(): - return cs.ctx.Err() - case <-cs.s.recvClose: - // If recv has a pending message, process that first - select { - case msg = <-cs.s.recv: - default: - return cs.s.recvErr - } - case msg = <-cs.s.recv: - } - - if msg.header.Type == messageTypeResponse { - resp := &Response{} - err := proto.Unmarshal(msg.payload[:msg.header.Length], resp) - // return the payload buffer for reuse - cs.c.channel.putmbuf(msg.payload) - if err != nil { - return err - } - - if err := cs.c.codec.Unmarshal(resp.Payload, m); err != nil { - return err - } - - if resp.Status != nil && resp.Status.Code != int32(codes.OK) { - return status.ErrorProto(resp.Status) - } - - cs.c.deleteStream(cs.s) - cs.remoteClosed = true - - return nil - } else if msg.header.Type == messageTypeData { - if !cs.desc.StreamingServer { - cs.c.deleteStream(cs.s) - cs.remoteClosed = true - return fmt.Errorf("received data from non-streaming server: %w", ErrProtocol) - } - if msg.header.Flags&flagRemoteClosed == flagRemoteClosed { - cs.c.deleteStream(cs.s) - cs.remoteClosed = true - - if msg.header.Flags&flagNoData == flagNoData { - return io.EOF - } - } - - err := cs.c.codec.Unmarshal(msg.payload[:msg.header.Length], m) - cs.c.channel.putmbuf(msg.payload) - if err != nil { - return err - } - return nil - } - - return fmt.Errorf("unexpected %q message received: %w", msg.header.Type, ErrProtocol) -} - -// Close closes the ttrpc connection and underlying connection -func (c *Client) Close() error { - c.closeOnce.Do(func() { - c.closed() - - c.conn.Close() - }) - return nil -} - -// UserOnCloseWait is used to block until the user's on-close callback -// finishes. -func (c *Client) UserOnCloseWait(ctx context.Context) error { - select { - case <-c.userCloseWaitCh: - return nil - case <-ctx.Done(): - return ctx.Err() - } -} - -func (c *Client) run() { - err := c.receiveLoop() - c.Close() - c.cleanupStreams(err) - - c.userCloseFunc() - close(c.userCloseWaitCh) -} - -func (c *Client) receiveLoop() error { - for { - select { - case <-c.ctx.Done(): - return ErrClosed - default: - var ( - msg = &streamMessage{} - err error - ) - - msg.header, msg.payload, err = c.channel.recv() - if err != nil { - _, ok := status.FromError(err) - if !ok { - // treat all errors that are not an rpc status as terminal. - // all others poison the connection. - return filterCloseErr(err) - } - } - sid := streamID(msg.header.StreamID) - s := c.getStream(sid) - if s == nil { - log.G(c.ctx).WithField("stream", sid).Error("ttrpc: received message on inactive stream") - continue - } - - if err != nil { - s.closeWithError(err) - } else { - if err := s.receive(c.ctx, msg); err != nil { - log.G(c.ctx).WithFields(log.Fields{"error": err, "stream": sid}).Error("ttrpc: failed to handle message") - } - } - } - } -} - -// createStream creates a new stream and registers it with the client -// Introduce stream types for multiple or single response -func (c *Client) createStream(flags uint8, b []byte) (*stream, error) { - // sendLock must be held across both allocation of the stream ID and sending it across the wire. - // This ensures that new stream IDs sent on the wire are always increasing, which is a - // requirement of the TTRPC protocol. - // This use of sendLock could be split into another mutex that covers stream creation + first send, - // and just use sendLock to guard writing to the wire, but for now it seems simpler to have fewer mutexes. - c.sendLock.Lock() - defer c.sendLock.Unlock() - - // Check if closed since lock acquired to prevent adding - // anything after cleanup completes - select { - case <-c.ctx.Done(): - return nil, ErrClosed - default: - } - - var s *stream - if err := func() error { - // In the future this could be replaced with a sync.Map instead of streamLock+map. - c.streamLock.Lock() - defer c.streamLock.Unlock() - - // Check if closed since lock acquired to prevent adding - // anything after cleanup completes - select { - case <-c.ctx.Done(): - return ErrClosed - default: - } - - s = newStream(c.nextStreamID, c) - c.streams[s.id] = s - c.nextStreamID = c.nextStreamID + 2 - - return nil - }(); err != nil { - return nil, err - } - - if err := c.channel.send(uint32(s.id), messageTypeRequest, flags, b); err != nil { - return s, filterCloseErr(err) - } - - return s, nil -} - -func (c *Client) deleteStream(s *stream) { - c.streamLock.Lock() - delete(c.streams, s.id) - c.streamLock.Unlock() - s.closeWithError(nil) -} - -func (c *Client) getStream(sid streamID) *stream { - c.streamLock.RLock() - s := c.streams[sid] - c.streamLock.RUnlock() - return s -} - -func (c *Client) cleanupStreams(err error) { - c.streamLock.Lock() - defer c.streamLock.Unlock() - - for sid, s := range c.streams { - s.closeWithError(err) - delete(c.streams, sid) - } -} - -// filterCloseErr rewrites EOF and EPIPE errors to ErrClosed. Use when -// returning from call or handling errors from main read loop. -// -// This purposely ignores errors with a wrapped cause. -func filterCloseErr(err error) error { - switch { - case err == nil: - return nil - case err == io.EOF: - return ErrClosed - case errors.Is(err, io.ErrClosedPipe): - return ErrClosed - case errors.Is(err, io.EOF): - return ErrClosed - case strings.Contains(err.Error(), "use of closed network connection"): - return ErrClosed - default: - // if we have an epipe on a write or econnreset on a read , we cast to errclosed - var oerr *net.OpError - if errors.As(err, &oerr) { - if (oerr.Op == "write" && errors.Is(err, syscall.EPIPE)) || - (oerr.Op == "read" && errors.Is(err, syscall.ECONNRESET)) { - return ErrClosed - } - } - } - - return err -} - -// NewStream creates a new stream with the given stream descriptor to the -// specified service and method. If not a streaming client, the request object -// may be provided. -func (c *Client) NewStream(ctx context.Context, desc *StreamDesc, service, method string, req interface{}) (ClientStream, error) { - var payload []byte - if req != nil { - var err error - payload, err = c.codec.Marshal(req) - if err != nil { - return nil, err - } - } - - request := &Request{ - Service: service, - Method: method, - Payload: payload, - // TODO: metadata from context - } - p, err := c.codec.Marshal(request) - if err != nil { - return nil, err - } - - var flags uint8 - if desc.StreamingClient { - flags = flagRemoteOpen - } else { - flags = flagRemoteClosed - } - s, err := c.createStream(flags, p) - if err != nil { - return nil, err - } - - return &clientStream{ - ctx: ctx, - s: s, - c: c, - desc: desc, - }, nil -} - -func (c *Client) dispatch(ctx context.Context, req *Request, resp *Response) error { - p, err := c.codec.Marshal(req) - if err != nil { - return err - } - - s, err := c.createStream(0, p) - if err != nil { - return err - } - defer c.deleteStream(s) - - var msg *streamMessage - select { - case <-ctx.Done(): - return ctx.Err() - case <-c.ctx.Done(): - return ErrClosed - case <-s.recvClose: - // If recv has a pending message, process that first - select { - case msg = <-s.recv: - default: - return s.recvErr - } - case msg = <-s.recv: - } - - if msg.header.Type == messageTypeResponse { - err = proto.Unmarshal(msg.payload[:msg.header.Length], resp) - } else { - err = fmt.Errorf("unexpected %q message received: %w", msg.header.Type, ErrProtocol) - } - - // return the payload buffer for reuse - c.channel.putmbuf(msg.payload) - - return err -} diff --git a/vendor/github.com/containerd/ttrpc/codec.go b/vendor/github.com/containerd/ttrpc/codec.go deleted file mode 100644 index 3e82722a4..000000000 --- a/vendor/github.com/containerd/ttrpc/codec.go +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "fmt" - - "google.golang.org/protobuf/proto" -) - -type codec struct{} - -func (c codec) Marshal(msg interface{}) ([]byte, error) { - switch v := msg.(type) { - case proto.Message: - return proto.Marshal(v) - default: - return nil, fmt.Errorf("ttrpc: cannot marshal unknown type: %T", msg) - } -} - -func (c codec) Unmarshal(p []byte, msg interface{}) error { - switch v := msg.(type) { - case proto.Message: - return proto.Unmarshal(p, v) - default: - return fmt.Errorf("ttrpc: cannot unmarshal into unknown type: %T", msg) - } -} diff --git a/vendor/github.com/containerd/ttrpc/config.go b/vendor/github.com/containerd/ttrpc/config.go deleted file mode 100644 index f401f67be..000000000 --- a/vendor/github.com/containerd/ttrpc/config.go +++ /dev/null @@ -1,86 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "errors" -) - -type serverConfig struct { - handshaker Handshaker - interceptor UnaryServerInterceptor -} - -// ServerOpt for configuring a ttrpc server -type ServerOpt func(*serverConfig) error - -// WithServerHandshaker can be passed to NewServer to ensure that the -// handshaker is called before every connection attempt. -// -// Only one handshaker is allowed per server. -func WithServerHandshaker(handshaker Handshaker) ServerOpt { - return func(c *serverConfig) error { - if c.handshaker != nil { - return errors.New("only one handshaker allowed per server") - } - c.handshaker = handshaker - return nil - } -} - -// WithUnaryServerInterceptor sets the provided interceptor on the server -func WithUnaryServerInterceptor(i UnaryServerInterceptor) ServerOpt { - return func(c *serverConfig) error { - if c.interceptor != nil { - return errors.New("only one unchained interceptor allowed per server") - } - c.interceptor = i - return nil - } -} - -// WithChainUnaryServerInterceptor sets the provided chain of server interceptors -func WithChainUnaryServerInterceptor(interceptors ...UnaryServerInterceptor) ServerOpt { - return func(c *serverConfig) error { - if len(interceptors) == 0 { - return nil - } - if c.interceptor != nil { - interceptors = append([]UnaryServerInterceptor{c.interceptor}, interceptors...) - } - c.interceptor = func( - ctx context.Context, - unmarshal Unmarshaler, - info *UnaryServerInfo, - method Method) (interface{}, error) { - return interceptors[0](ctx, unmarshal, info, - chainUnaryServerInterceptors(info, method, interceptors[1:])) - } - return nil - } -} - -func chainUnaryServerInterceptors(info *UnaryServerInfo, method Method, interceptors []UnaryServerInterceptor) Method { - if len(interceptors) == 0 { - return method - } - return func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) { - return interceptors[0](ctx, unmarshal, info, - chainUnaryServerInterceptors(info, method, interceptors[1:])) - } -} diff --git a/vendor/github.com/containerd/ttrpc/doc.go b/vendor/github.com/containerd/ttrpc/doc.go deleted file mode 100644 index d80cd424c..000000000 --- a/vendor/github.com/containerd/ttrpc/doc.go +++ /dev/null @@ -1,23 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* -package ttrpc defines and implements a low level simple transfer protocol -optimized for low latency and reliable connections between processes on the same -host. The protocol uses simple framing for sending requests, responses, and data -using multiple streams. -*/ -package ttrpc diff --git a/vendor/github.com/containerd/ttrpc/errors.go b/vendor/github.com/containerd/ttrpc/errors.go deleted file mode 100644 index 632dbe8bd..000000000 --- a/vendor/github.com/containerd/ttrpc/errors.go +++ /dev/null @@ -1,80 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "errors" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -var ( - // ErrProtocol is a general error in the handling the protocol. - ErrProtocol = errors.New("protocol error") - - // ErrClosed is returned by client methods when the underlying connection is - // closed. - ErrClosed = errors.New("ttrpc: closed") - - // ErrServerClosed is returned when the Server has closed its connection. - ErrServerClosed = errors.New("ttrpc: server closed") - - // ErrStreamClosed is when the streaming connection is closed. - ErrStreamClosed = errors.New("ttrpc: stream closed") -) - -// OversizedMessageErr is used to indicate refusal to send an oversized message. -// It wraps a ResourceExhausted grpc Status together with the offending message -// length. -type OversizedMessageErr struct { - messageLength int - err error -} - -// OversizedMessageError returns an OversizedMessageErr error for the given message -// length if it exceeds the allowed maximum. Otherwise a nil error is returned. -func OversizedMessageError(messageLength int) error { - if messageLength <= messageLengthMax { - return nil - } - - return &OversizedMessageErr{ - messageLength: messageLength, - err: status.Errorf(codes.ResourceExhausted, "message length %v exceed maximum message size of %v", messageLength, messageLengthMax), - } -} - -// Error returns the error message for the corresponding grpc Status for the error. -func (e *OversizedMessageErr) Error() string { - return e.err.Error() -} - -// Unwrap returns the corresponding error with our grpc status code. -func (e *OversizedMessageErr) Unwrap() error { - return e.err -} - -// RejectedLength retrieves the rejected message length which triggered the error. -func (e *OversizedMessageErr) RejectedLength() int { - return e.messageLength -} - -// MaximumLength retrieves the maximum allowed message length that triggered the error. -func (*OversizedMessageErr) MaximumLength() int { - return messageLengthMax -} diff --git a/vendor/github.com/containerd/ttrpc/handshake.go b/vendor/github.com/containerd/ttrpc/handshake.go deleted file mode 100644 index 3c6b610d3..000000000 --- a/vendor/github.com/containerd/ttrpc/handshake.go +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "net" -) - -// Handshaker defines the interface for connection handshakes performed on the -// server or client when first connecting. -type Handshaker interface { - // Handshake should confirm or decorate a connection that may be incoming - // to a server or outgoing from a client. - // - // If this returns without an error, the caller should use the connection - // in place of the original connection. - // - // The second return value can contain credential specific data, such as - // unix socket credentials or TLS information. - // - // While we currently only have implementations on the server-side, this - // interface should be sufficient to implement similar handshakes on the - // client-side. - Handshake(ctx context.Context, conn net.Conn) (net.Conn, interface{}, error) -} - -type handshakerFunc func(ctx context.Context, conn net.Conn) (net.Conn, interface{}, error) - -func (fn handshakerFunc) Handshake(ctx context.Context, conn net.Conn) (net.Conn, interface{}, error) { - return fn(ctx, conn) -} - -func noopHandshake(_ context.Context, conn net.Conn) (net.Conn, interface{}, error) { - return conn, nil, nil -} diff --git a/vendor/github.com/containerd/ttrpc/interceptor.go b/vendor/github.com/containerd/ttrpc/interceptor.go deleted file mode 100644 index 7ff5e9d33..000000000 --- a/vendor/github.com/containerd/ttrpc/interceptor.go +++ /dev/null @@ -1,65 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import "context" - -// UnaryServerInfo provides information about the server request -type UnaryServerInfo struct { - FullMethod string -} - -// UnaryClientInfo provides information about the client request -type UnaryClientInfo struct { - FullMethod string -} - -// StreamServerInfo provides information about the server request -type StreamServerInfo struct { - FullMethod string - StreamingClient bool - StreamingServer bool -} - -// Unmarshaler contains the server request data and allows it to be unmarshaled -// into a concrete type -type Unmarshaler func(interface{}) error - -// Invoker invokes the client's request and response from the ttrpc server -type Invoker func(context.Context, *Request, *Response) error - -// UnaryServerInterceptor specifies the interceptor function for server request/response -type UnaryServerInterceptor func(context.Context, Unmarshaler, *UnaryServerInfo, Method) (interface{}, error) - -// UnaryClientInterceptor specifies the interceptor function for client request/response -type UnaryClientInterceptor func(context.Context, *Request, *Response, *UnaryClientInfo, Invoker) error - -func defaultServerInterceptor(ctx context.Context, unmarshal Unmarshaler, _ *UnaryServerInfo, method Method) (interface{}, error) { - return method(ctx, unmarshal) -} - -func defaultClientInterceptor(ctx context.Context, req *Request, resp *Response, _ *UnaryClientInfo, invoker Invoker) error { - return invoker(ctx, req, resp) -} - -type StreamServerInterceptor func(context.Context, StreamServer, *StreamServerInfo, StreamHandler) (interface{}, error) - -func defaultStreamServerInterceptor(ctx context.Context, ss StreamServer, _ *StreamServerInfo, stream StreamHandler) (interface{}, error) { - return stream(ctx, ss) -} - -type StreamClientInterceptor func(context.Context) diff --git a/vendor/github.com/containerd/ttrpc/metadata.go b/vendor/github.com/containerd/ttrpc/metadata.go deleted file mode 100644 index ce8c0d13c..000000000 --- a/vendor/github.com/containerd/ttrpc/metadata.go +++ /dev/null @@ -1,107 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "strings" -) - -// MD is the user type for ttrpc metadata -type MD map[string][]string - -// Get returns the metadata for a given key when they exist. -// If there is no metadata, a nil slice and false are returned. -func (m MD) Get(key string) ([]string, bool) { - key = strings.ToLower(key) - list, ok := m[key] - if !ok || len(list) == 0 { - return nil, false - } - - return list, true -} - -// Set sets the provided values for a given key. -// The values will overwrite any existing values. -// If no values provided, a key will be deleted. -func (m MD) Set(key string, values ...string) { - key = strings.ToLower(key) - if len(values) == 0 { - delete(m, key) - return - } - m[key] = values -} - -// Append appends additional values to the given key. -func (m MD) Append(key string, values ...string) { - key = strings.ToLower(key) - if len(values) == 0 { - return - } - current, ok := m[key] - if ok { - m.Set(key, append(current, values...)...) - } else { - m.Set(key, values...) - } -} - -func (m MD) setRequest(r *Request) { - for k, values := range m { - for _, v := range values { - r.Metadata = append(r.Metadata, &KeyValue{ - Key: k, - Value: v, - }) - } - } -} - -func (m MD) fromRequest(r *Request) { - for _, kv := range r.Metadata { - m[kv.Key] = append(m[kv.Key], kv.Value) - } -} - -type metadataKey struct{} - -// GetMetadata retrieves metadata from context.Context (previously attached with WithMetadata) -func GetMetadata(ctx context.Context) (MD, bool) { - metadata, ok := ctx.Value(metadataKey{}).(MD) - return metadata, ok -} - -// GetMetadataValue gets a specific metadata value by name from context.Context -func GetMetadataValue(ctx context.Context, name string) (string, bool) { - metadata, ok := GetMetadata(ctx) - if !ok { - return "", false - } - - if list, ok := metadata.Get(name); ok { - return list[0], true - } - - return "", false -} - -// WithMetadata attaches metadata map to a context.Context -func WithMetadata(ctx context.Context, md MD) context.Context { - return context.WithValue(ctx, metadataKey{}, md) -} diff --git a/vendor/github.com/containerd/ttrpc/request.pb.go b/vendor/github.com/containerd/ttrpc/request.pb.go deleted file mode 100644 index 3921ae5a3..000000000 --- a/vendor/github.com/containerd/ttrpc/request.pb.go +++ /dev/null @@ -1,396 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.28.1 -// protoc v3.20.1 -// source: github.com/containerd/ttrpc/request.proto - -package ttrpc - -import ( - status "google.golang.org/genproto/googleapis/rpc/status" - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -type Request struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Service string `protobuf:"bytes,1,opt,name=service,proto3" json:"service,omitempty"` - Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` - Payload []byte `protobuf:"bytes,3,opt,name=payload,proto3" json:"payload,omitempty"` - TimeoutNano int64 `protobuf:"varint,4,opt,name=timeout_nano,json=timeoutNano,proto3" json:"timeout_nano,omitempty"` - Metadata []*KeyValue `protobuf:"bytes,5,rep,name=metadata,proto3" json:"metadata,omitempty"` -} - -func (x *Request) Reset() { - *x = Request{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Request) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Request) ProtoMessage() {} - -func (x *Request) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Request.ProtoReflect.Descriptor instead. -func (*Request) Descriptor() ([]byte, []int) { - return file_github_com_containerd_ttrpc_request_proto_rawDescGZIP(), []int{0} -} - -func (x *Request) GetService() string { - if x != nil { - return x.Service - } - return "" -} - -func (x *Request) GetMethod() string { - if x != nil { - return x.Method - } - return "" -} - -func (x *Request) GetPayload() []byte { - if x != nil { - return x.Payload - } - return nil -} - -func (x *Request) GetTimeoutNano() int64 { - if x != nil { - return x.TimeoutNano - } - return 0 -} - -func (x *Request) GetMetadata() []*KeyValue { - if x != nil { - return x.Metadata - } - return nil -} - -type Response struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Status *status.Status `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"` - Payload []byte `protobuf:"bytes,2,opt,name=payload,proto3" json:"payload,omitempty"` -} - -func (x *Response) Reset() { - *x = Response{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *Response) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*Response) ProtoMessage() {} - -func (x *Response) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use Response.ProtoReflect.Descriptor instead. -func (*Response) Descriptor() ([]byte, []int) { - return file_github_com_containerd_ttrpc_request_proto_rawDescGZIP(), []int{1} -} - -func (x *Response) GetStatus() *status.Status { - if x != nil { - return x.Status - } - return nil -} - -func (x *Response) GetPayload() []byte { - if x != nil { - return x.Payload - } - return nil -} - -type StringList struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - List []string `protobuf:"bytes,1,rep,name=list,proto3" json:"list,omitempty"` -} - -func (x *StringList) Reset() { - *x = StringList{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *StringList) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*StringList) ProtoMessage() {} - -func (x *StringList) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use StringList.ProtoReflect.Descriptor instead. -func (*StringList) Descriptor() ([]byte, []int) { - return file_github_com_containerd_ttrpc_request_proto_rawDescGZIP(), []int{2} -} - -func (x *StringList) GetList() []string { - if x != nil { - return x.List - } - return nil -} - -type KeyValue struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` -} - -func (x *KeyValue) Reset() { - *x = KeyValue{} - if protoimpl.UnsafeEnabled { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *KeyValue) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*KeyValue) ProtoMessage() {} - -func (x *KeyValue) ProtoReflect() protoreflect.Message { - mi := &file_github_com_containerd_ttrpc_request_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use KeyValue.ProtoReflect.Descriptor instead. -func (*KeyValue) Descriptor() ([]byte, []int) { - return file_github_com_containerd_ttrpc_request_proto_rawDescGZIP(), []int{3} -} - -func (x *KeyValue) GetKey() string { - if x != nil { - return x.Key - } - return "" -} - -func (x *KeyValue) GetValue() string { - if x != nil { - return x.Value - } - return "" -} - -var File_github_com_containerd_ttrpc_request_proto protoreflect.FileDescriptor - -var file_github_com_containerd_ttrpc_request_proto_rawDesc = []byte{ - 0x0a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x74, 0x74, 0x72, 0x70, 0x63, 0x2f, 0x72, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x74, 0x74, 0x72, - 0x70, 0x63, 0x1a, 0x12, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xa5, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x06, - 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, - 0x74, 0x68, 0x6f, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x21, - 0x0a, 0x0c, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x6e, 0x61, 0x6e, 0x6f, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x4e, 0x61, 0x6e, - 0x6f, 0x12, 0x2b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x74, 0x74, 0x72, 0x70, 0x63, 0x2e, 0x4b, 0x65, 0x79, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x45, - 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1f, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x07, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x70, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x70, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x22, 0x20, 0x0a, 0x0a, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4c, - 0x69, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x04, 0x6c, 0x69, 0x73, 0x74, 0x22, 0x32, 0x0a, 0x08, 0x4b, 0x65, 0x79, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x1d, 0x5a, 0x1b, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x74, 0x74, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, -} - -var ( - file_github_com_containerd_ttrpc_request_proto_rawDescOnce sync.Once - file_github_com_containerd_ttrpc_request_proto_rawDescData = file_github_com_containerd_ttrpc_request_proto_rawDesc -) - -func file_github_com_containerd_ttrpc_request_proto_rawDescGZIP() []byte { - file_github_com_containerd_ttrpc_request_proto_rawDescOnce.Do(func() { - file_github_com_containerd_ttrpc_request_proto_rawDescData = protoimpl.X.CompressGZIP(file_github_com_containerd_ttrpc_request_proto_rawDescData) - }) - return file_github_com_containerd_ttrpc_request_proto_rawDescData -} - -var file_github_com_containerd_ttrpc_request_proto_msgTypes = make([]protoimpl.MessageInfo, 4) -var file_github_com_containerd_ttrpc_request_proto_goTypes = []interface{}{ - (*Request)(nil), // 0: ttrpc.Request - (*Response)(nil), // 1: ttrpc.Response - (*StringList)(nil), // 2: ttrpc.StringList - (*KeyValue)(nil), // 3: ttrpc.KeyValue - (*status.Status)(nil), // 4: Status -} -var file_github_com_containerd_ttrpc_request_proto_depIdxs = []int32{ - 3, // 0: ttrpc.Request.metadata:type_name -> ttrpc.KeyValue - 4, // 1: ttrpc.Response.status:type_name -> Status - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name -} - -func init() { file_github_com_containerd_ttrpc_request_proto_init() } -func file_github_com_containerd_ttrpc_request_proto_init() { - if File_github_com_containerd_ttrpc_request_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_github_com_containerd_ttrpc_request_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Request); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_ttrpc_request_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Response); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_ttrpc_request_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*StringList); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_github_com_containerd_ttrpc_request_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyValue); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_github_com_containerd_ttrpc_request_proto_rawDesc, - NumEnums: 0, - NumMessages: 4, - NumExtensions: 0, - NumServices: 0, - }, - GoTypes: file_github_com_containerd_ttrpc_request_proto_goTypes, - DependencyIndexes: file_github_com_containerd_ttrpc_request_proto_depIdxs, - MessageInfos: file_github_com_containerd_ttrpc_request_proto_msgTypes, - }.Build() - File_github_com_containerd_ttrpc_request_proto = out.File - file_github_com_containerd_ttrpc_request_proto_rawDesc = nil - file_github_com_containerd_ttrpc_request_proto_goTypes = nil - file_github_com_containerd_ttrpc_request_proto_depIdxs = nil -} diff --git a/vendor/github.com/containerd/ttrpc/request.proto b/vendor/github.com/containerd/ttrpc/request.proto deleted file mode 100644 index 37da334fc..000000000 --- a/vendor/github.com/containerd/ttrpc/request.proto +++ /dev/null @@ -1,29 +0,0 @@ -syntax = "proto3"; - -package ttrpc; - -import "proto/status.proto"; - -option go_package = "github.com/containerd/ttrpc"; - -message Request { - string service = 1; - string method = 2; - bytes payload = 3; - int64 timeout_nano = 4; - repeated KeyValue metadata = 5; -} - -message Response { - Status status = 1; - bytes payload = 2; -} - -message StringList { - repeated string list = 1; -} - -message KeyValue { - string key = 1; - string value = 2; -} diff --git a/vendor/github.com/containerd/ttrpc/server.go b/vendor/github.com/containerd/ttrpc/server.go deleted file mode 100644 index 26419831d..000000000 --- a/vendor/github.com/containerd/ttrpc/server.go +++ /dev/null @@ -1,579 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "errors" - "io" - "math/rand" - "net" - "sync" - "sync/atomic" - "syscall" - "time" - - "github.com/containerd/log" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" -) - -type Server struct { - config *serverConfig - services *serviceSet - codec codec - - mu sync.Mutex - listeners map[net.Listener]struct{} - connections map[*serverConn]struct{} // all connections to current state - done chan struct{} // marks point at which we stop serving requests -} - -func NewServer(opts ...ServerOpt) (*Server, error) { - config := &serverConfig{} - for _, opt := range opts { - if err := opt(config); err != nil { - return nil, err - } - } - if config.interceptor == nil { - config.interceptor = defaultServerInterceptor - } - - return &Server{ - config: config, - services: newServiceSet(config.interceptor), - done: make(chan struct{}), - listeners: make(map[net.Listener]struct{}), - connections: make(map[*serverConn]struct{}), - }, nil -} - -// Register registers a map of methods to method handlers -// TODO: Remove in 2.0, does not support streams -func (s *Server) Register(name string, methods map[string]Method) { - s.services.register(name, &ServiceDesc{Methods: methods}) -} - -func (s *Server) RegisterService(name string, desc *ServiceDesc) { - s.services.register(name, desc) -} - -func (s *Server) Serve(ctx context.Context, l net.Listener) error { - s.addListener(l) - defer s.closeListener(l) - - var ( - backoff time.Duration - handshaker = s.config.handshaker - ) - - if handshaker == nil { - handshaker = handshakerFunc(noopHandshake) - } - - for { - conn, err := l.Accept() - if err != nil { - select { - case <-s.done: - return ErrServerClosed - default: - } - - if terr, ok := err.(interface { - Temporary() bool - }); ok && terr.Temporary() { - if backoff == 0 { - backoff = time.Millisecond - } else { - backoff *= 2 - } - - if max := time.Second; backoff > max { - backoff = max - } - - sleep := time.Duration(rand.Int63n(int64(backoff))) - log.G(ctx).WithError(err).Errorf("ttrpc: failed accept; backoff %v", sleep) - time.Sleep(sleep) - continue - } - - return err - } - - backoff = 0 - - approved, handshake, err := handshaker.Handshake(ctx, conn) - if err != nil { - log.G(ctx).WithError(err).Error("ttrpc: refusing connection after handshake") - conn.Close() - continue - } - - sc, err := s.newConn(approved, handshake) - if err != nil { - log.G(ctx).WithError(err).Error("ttrpc: create connection failed") - conn.Close() - continue - } - - go sc.run(ctx) - } -} - -func (s *Server) Shutdown(ctx context.Context) error { - s.mu.Lock() - select { - case <-s.done: - default: - // protected by mutex - close(s.done) - } - lnerr := s.closeListeners() - s.mu.Unlock() - - ticker := time.NewTicker(200 * time.Millisecond) - defer ticker.Stop() - for { - s.closeIdleConns() - - if s.countConnection() == 0 { - break - } - - select { - case <-ctx.Done(): - return ctx.Err() - case <-ticker.C: - } - } - - return lnerr -} - -// Close the server without waiting for active connections. -func (s *Server) Close() error { - s.mu.Lock() - defer s.mu.Unlock() - - select { - case <-s.done: - default: - // protected by mutex - close(s.done) - } - - err := s.closeListeners() - for c := range s.connections { - c.close() - delete(s.connections, c) - } - - return err -} - -func (s *Server) addListener(l net.Listener) { - s.mu.Lock() - defer s.mu.Unlock() - s.listeners[l] = struct{}{} -} - -func (s *Server) closeListener(l net.Listener) error { - s.mu.Lock() - defer s.mu.Unlock() - - return s.closeListenerLocked(l) -} - -func (s *Server) closeListenerLocked(l net.Listener) error { - defer delete(s.listeners, l) - return l.Close() -} - -func (s *Server) closeListeners() error { - var err error - for l := range s.listeners { - if cerr := s.closeListenerLocked(l); cerr != nil && err == nil { - err = cerr - } - } - return err -} - -func (s *Server) addConnection(c *serverConn) error { - s.mu.Lock() - defer s.mu.Unlock() - - select { - case <-s.done: - return ErrServerClosed - default: - } - - s.connections[c] = struct{}{} - return nil -} - -func (s *Server) delConnection(c *serverConn) { - s.mu.Lock() - defer s.mu.Unlock() - - delete(s.connections, c) -} - -func (s *Server) countConnection() int { - s.mu.Lock() - defer s.mu.Unlock() - - return len(s.connections) -} - -func (s *Server) closeIdleConns() { - s.mu.Lock() - defer s.mu.Unlock() - - for c := range s.connections { - if st, ok := c.getState(); !ok || st == connStateActive { - continue - } - c.close() - delete(s.connections, c) - } -} - -type connState int - -const ( - connStateActive = iota + 1 // outstanding requests - connStateIdle // no requests - connStateClosed // closed connection -) - -func (cs connState) String() string { - switch cs { - case connStateActive: - return "active" - case connStateIdle: - return "idle" - case connStateClosed: - return "closed" - default: - return "unknown" - } -} - -func (s *Server) newConn(conn net.Conn, handshake interface{}) (*serverConn, error) { - c := &serverConn{ - server: s, - conn: conn, - handshake: handshake, - shutdown: make(chan struct{}), - } - c.setState(connStateIdle) - if err := s.addConnection(c); err != nil { - c.close() - return nil, err - } - return c, nil -} - -type serverConn struct { - server *Server - conn net.Conn - handshake interface{} // data from handshake, not used for now - state atomic.Value - - shutdownOnce sync.Once - shutdown chan struct{} // forced shutdown, used by close -} - -func (c *serverConn) getState() (connState, bool) { - cs, ok := c.state.Load().(connState) - return cs, ok -} - -func (c *serverConn) setState(newstate connState) { - c.state.Store(newstate) -} - -func (c *serverConn) close() error { - c.shutdownOnce.Do(func() { - close(c.shutdown) - }) - - return nil -} - -func (c *serverConn) run(sctx context.Context) { - type ( - response struct { - id uint32 - status *status.Status - data []byte - closeStream bool - streaming bool - } - ) - - var ( - ch = newChannel(c.conn) - ctx, cancel = context.WithCancel(sctx) - state connState = connStateIdle - responses = make(chan response) - recvErr = make(chan error, 1) - done = make(chan struct{}) - streams = sync.Map{} - active int32 - lastStreamID uint32 - ) - - defer c.conn.Close() - defer cancel() - defer close(done) - defer c.server.delConnection(c) - - sendStatus := func(id uint32, st *status.Status) bool { - select { - case responses <- response{ - // even though we've had an invalid stream id, we send it - // back on the same stream id so the client knows which - // stream id was bad. - id: id, - status: st, - closeStream: true, - }: - return true - case <-c.shutdown: - return false - case <-done: - return false - } - } - - go func(recvErr chan error) { - defer close(recvErr) - for { - select { - case <-c.shutdown: - return - case <-done: - return - default: // proceed - } - - mh, p, err := ch.recv() - if err != nil { - status, ok := status.FromError(err) - if !ok { - recvErr <- err - return - } - - // in this case, we send an error for that particular message - // when the status is defined. - if !sendStatus(mh.StreamID, status) { - return - } - - continue - } - - if mh.StreamID%2 != 1 { - // enforce odd client initiated identifiers. - if !sendStatus(mh.StreamID, status.Newf(codes.InvalidArgument, "StreamID must be odd for client initiated streams")) { - return - } - continue - } - - if mh.Type == messageTypeData { - i, ok := streams.Load(mh.StreamID) - if !ok { - if !sendStatus(mh.StreamID, status.Newf(codes.InvalidArgument, "StreamID is no longer active")) { - return - } - } - sh := i.(*streamHandler) - if mh.Flags&flagNoData != flagNoData { - unmarshal := func(obj interface{}) error { - err := protoUnmarshal(p, obj) - ch.putmbuf(p) - return err - } - - if err := sh.data(unmarshal); err != nil { - if !sendStatus(mh.StreamID, status.Newf(codes.InvalidArgument, "data handling error: %v", err)) { - return - } - } - } - - if mh.Flags&flagRemoteClosed == flagRemoteClosed { - sh.closeSend() - if len(p) > 0 { - if !sendStatus(mh.StreamID, status.Newf(codes.InvalidArgument, "data close message cannot include data")) { - return - } - } - } - } else if mh.Type == messageTypeRequest { - if mh.StreamID <= lastStreamID { - // enforce odd client initiated identifiers. - if !sendStatus(mh.StreamID, status.Newf(codes.InvalidArgument, "StreamID cannot be re-used and must increment")) { - return - } - continue - - } - lastStreamID = mh.StreamID - - // TODO: Make request type configurable - // Unmarshaller which takes in a byte array and returns an interface? - var req Request - if err := c.server.codec.Unmarshal(p, &req); err != nil { - ch.putmbuf(p) - if !sendStatus(mh.StreamID, status.Newf(codes.InvalidArgument, "unmarshal request error: %v", err)) { - return - } - continue - } - ch.putmbuf(p) - - id := mh.StreamID - respond := func(status *status.Status, data []byte, streaming, closeStream bool) error { - select { - case responses <- response{ - id: id, - status: status, - data: data, - closeStream: closeStream, - streaming: streaming, - }: - case <-done: - return ErrClosed - } - return nil - } - sh, err := c.server.services.handle(ctx, &req, respond) - if err != nil { - status, _ := status.FromError(err) - if !sendStatus(mh.StreamID, status) { - return - } - continue - } - - streams.Store(id, sh) - atomic.AddInt32(&active, 1) - } - // TODO: else we must ignore this for future compat. log this? - } - }(recvErr) - - for { - var ( - newstate connState - shutdown chan struct{} - ) - - activeN := atomic.LoadInt32(&active) - if activeN > 0 { - newstate = connStateActive - shutdown = nil - } else { - newstate = connStateIdle - shutdown = c.shutdown // only enable this branch in idle mode - } - if newstate != state { - c.setState(newstate) - state = newstate - } - - select { - case response := <-responses: - if !response.streaming || response.status.Code() != codes.OK { - p, err := c.server.codec.Marshal(&Response{ - Status: response.status.Proto(), - Payload: response.data, - }) - if err != nil { - log.G(ctx).WithError(err).Error("failed marshaling response") - return - } - - if err := ch.send(response.id, messageTypeResponse, 0, p); err != nil { - log.G(ctx).WithError(err).Error("failed sending message on channel") - return - } - } else { - var flags uint8 - if response.closeStream { - flags = flagRemoteClosed - } - if response.data == nil { - flags = flags | flagNoData - } - if err := ch.send(response.id, messageTypeData, flags, response.data); err != nil { - log.G(ctx).WithError(err).Error("failed sending message on channel") - return - } - } - - if response.closeStream { - // The ttrpc protocol currently does not support the case where - // the server is localClosed but not remoteClosed. Once the server - // is closing, the whole stream may be considered finished - streams.Delete(response.id) - atomic.AddInt32(&active, -1) - } - case err := <-recvErr: - // TODO(stevvooe): Not wildly clear what we should do in this - // branch. Basically, it means that we are no longer receiving - // requests due to a terminal error. - recvErr = nil // connection is now "closing" - if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, syscall.ECONNRESET) { - // The client went away and we should stop processing - // requests, so that the client connection is closed - return - } - log.G(ctx).WithError(err).Error("error receiving message") - // else, initiate shutdown - case <-shutdown: - return - } - } -} - -var noopFunc = func() {} - -func getRequestContext(ctx context.Context, req *Request) (retCtx context.Context, cancel func()) { - if len(req.Metadata) > 0 { - md := MD{} - md.fromRequest(req) - ctx = WithMetadata(ctx, md) - } - - cancel = noopFunc - if req.TimeoutNano == 0 { - return ctx, cancel - } - - ctx, cancel = context.WithTimeout(ctx, time.Duration(req.TimeoutNano)) - return ctx, cancel -} diff --git a/vendor/github.com/containerd/ttrpc/services.go b/vendor/github.com/containerd/ttrpc/services.go deleted file mode 100644 index 6d092bf95..000000000 --- a/vendor/github.com/containerd/ttrpc/services.go +++ /dev/null @@ -1,279 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "errors" - "fmt" - "io" - "os" - "path" - "unsafe" - - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/proto" -) - -type Method func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) - -type StreamHandler func(context.Context, StreamServer) (interface{}, error) - -type Stream struct { - Handler StreamHandler - StreamingClient bool - StreamingServer bool -} - -type ServiceDesc struct { - Methods map[string]Method - Streams map[string]Stream -} - -type serviceSet struct { - services map[string]*ServiceDesc - unaryInterceptor UnaryServerInterceptor - streamInterceptor StreamServerInterceptor -} - -func newServiceSet(interceptor UnaryServerInterceptor) *serviceSet { - return &serviceSet{ - services: make(map[string]*ServiceDesc), - unaryInterceptor: interceptor, - streamInterceptor: defaultStreamServerInterceptor, - } -} - -func (s *serviceSet) register(name string, desc *ServiceDesc) { - if _, ok := s.services[name]; ok { - panic(fmt.Errorf("duplicate service %v registered", name)) - } - - s.services[name] = desc -} - -func (s *serviceSet) unaryCall(ctx context.Context, method Method, info *UnaryServerInfo, data []byte) (p []byte, st *status.Status) { - unmarshal := func(obj interface{}) error { - return protoUnmarshal(data, obj) - } - - resp, err := s.unaryInterceptor(ctx, unmarshal, info, method) - if err == nil { - if isNil(resp) { - err = errors.New("ttrpc: marshal called with nil") - } else { - p, err = protoMarshal(resp) - } - } - - st, ok := status.FromError(err) - if !ok { - st = status.New(convertCode(err), err.Error()) - } - - return p, st -} - -func (s *serviceSet) streamCall(ctx context.Context, stream StreamHandler, info *StreamServerInfo, ss StreamServer) (p []byte, st *status.Status) { - resp, err := s.streamInterceptor(ctx, ss, info, stream) - if err == nil { - p, err = protoMarshal(resp) - } - st, ok := status.FromError(err) - if !ok { - st = status.New(convertCode(err), err.Error()) - } - return -} - -func (s *serviceSet) handle(ctx context.Context, req *Request, respond func(*status.Status, []byte, bool, bool) error) (*streamHandler, error) { - srv, ok := s.services[req.Service] - if !ok { - return nil, status.Errorf(codes.Unimplemented, "service %v", req.Service) - } - - if method, ok := srv.Methods[req.Method]; ok { - go func() { - ctx, cancel := getRequestContext(ctx, req) - defer cancel() - - info := &UnaryServerInfo{ - FullMethod: fullPath(req.Service, req.Method), - } - p, st := s.unaryCall(ctx, method, info, req.Payload) - - respond(st, p, false, true) - }() - return nil, nil - } - if stream, ok := srv.Streams[req.Method]; ok { - ctx, cancel := getRequestContext(ctx, req) - info := &StreamServerInfo{ - FullMethod: fullPath(req.Service, req.Method), - StreamingClient: stream.StreamingClient, - StreamingServer: stream.StreamingServer, - } - sh := &streamHandler{ - ctx: ctx, - respond: respond, - recv: make(chan Unmarshaler, 5), - info: info, - } - go func() { - defer cancel() - p, st := s.streamCall(ctx, stream.Handler, info, sh) - respond(st, p, stream.StreamingServer, true) - }() - - // Empty proto messages serialized to 0 payloads, - // so signatures like: rpc Stream(google.protobuf.Empty) returns (stream Data); - // don't get invoked here, which causes hang on client side. - // See https://github.com/containerd/ttrpc/issues/126 - if req.Payload != nil || !info.StreamingClient { - unmarshal := func(obj interface{}) error { - return protoUnmarshal(req.Payload, obj) - } - if err := sh.data(unmarshal); err != nil { - return nil, err - } - } - - return sh, nil - } - return nil, status.Errorf(codes.Unimplemented, "method %v", req.Method) -} - -type streamHandler struct { - ctx context.Context - respond func(*status.Status, []byte, bool, bool) error - recv chan Unmarshaler - info *StreamServerInfo - - remoteClosed bool - localClosed bool -} - -func (s *streamHandler) closeSend() { - if !s.remoteClosed { - s.remoteClosed = true - close(s.recv) - } -} - -func (s *streamHandler) data(unmarshal Unmarshaler) error { - if s.remoteClosed { - return ErrStreamClosed - } - select { - case s.recv <- unmarshal: - return nil - case <-s.ctx.Done(): - return s.ctx.Err() - } -} - -func (s *streamHandler) SendMsg(m interface{}) error { - if s.localClosed { - return ErrStreamClosed - } - p, err := protoMarshal(m) - if err != nil { - return err - } - return s.respond(nil, p, true, false) -} - -func (s *streamHandler) RecvMsg(m interface{}) error { - select { - case unmarshal, ok := <-s.recv: - if !ok { - return io.EOF - } - return unmarshal(m) - case <-s.ctx.Done(): - return s.ctx.Err() - - } -} - -func protoUnmarshal(p []byte, obj interface{}) error { - switch v := obj.(type) { - case proto.Message: - if err := proto.Unmarshal(p, v); err != nil { - return status.Errorf(codes.Internal, "ttrpc: error unmarshalling payload: %v", err.Error()) - } - default: - return status.Errorf(codes.Internal, "ttrpc: error unsupported request type: %T", v) - } - return nil -} - -func protoMarshal(obj interface{}) ([]byte, error) { - if obj == nil { - return nil, nil - } - - switch v := obj.(type) { - case proto.Message: - r, err := proto.Marshal(v) - if err != nil { - return nil, status.Errorf(codes.Internal, "ttrpc: error marshaling payload: %v", err.Error()) - } - - return r, nil - default: - return nil, status.Errorf(codes.Internal, "ttrpc: error unsupported response type: %T", v) - } -} - -// convertCode maps stdlib go errors into grpc space. -// -// This is ripped from the grpc-go code base. -func convertCode(err error) codes.Code { - switch err { - case nil: - return codes.OK - case io.EOF: - return codes.OutOfRange - case io.ErrClosedPipe, io.ErrNoProgress, io.ErrShortBuffer, io.ErrShortWrite, io.ErrUnexpectedEOF: - return codes.FailedPrecondition - case os.ErrInvalid: - return codes.InvalidArgument - case context.Canceled: - return codes.Canceled - case context.DeadlineExceeded: - return codes.DeadlineExceeded - } - switch { - case os.IsExist(err): - return codes.AlreadyExists - case os.IsNotExist(err): - return codes.NotFound - case os.IsPermission(err): - return codes.PermissionDenied - } - return codes.Unknown -} - -func fullPath(service, method string) string { - return "/" + path.Join(service, method) -} - -func isNil(resp interface{}) bool { - return (*[2]uintptr)(unsafe.Pointer(&resp))[1] == 0 -} diff --git a/vendor/github.com/containerd/ttrpc/stream.go b/vendor/github.com/containerd/ttrpc/stream.go deleted file mode 100644 index 739a4c967..000000000 --- a/vendor/github.com/containerd/ttrpc/stream.go +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "sync" -) - -type streamID uint32 - -type streamMessage struct { - header messageHeader - payload []byte -} - -type stream struct { - id streamID - sender sender - recv chan *streamMessage - - closeOnce sync.Once - recvErr error - recvClose chan struct{} -} - -func newStream(id streamID, send sender) *stream { - return &stream{ - id: id, - sender: send, - recv: make(chan *streamMessage, 1), - recvClose: make(chan struct{}), - } -} - -func (s *stream) closeWithError(err error) error { - s.closeOnce.Do(func() { - if err != nil { - s.recvErr = err - } else { - s.recvErr = ErrClosed - } - close(s.recvClose) - }) - return nil -} - -func (s *stream) send(mt messageType, flags uint8, b []byte) error { - return s.sender.send(uint32(s.id), mt, flags, b) -} - -func (s *stream) receive(ctx context.Context, msg *streamMessage) error { - select { - case <-s.recvClose: - return s.recvErr - default: - } - select { - case <-s.recvClose: - return s.recvErr - case s.recv <- msg: - return nil - case <-ctx.Done(): - return ctx.Err() - } -} - -type sender interface { - send(uint32, messageType, uint8, []byte) error -} diff --git a/vendor/github.com/containerd/ttrpc/stream_server.go b/vendor/github.com/containerd/ttrpc/stream_server.go deleted file mode 100644 index b6d1ba720..000000000 --- a/vendor/github.com/containerd/ttrpc/stream_server.go +++ /dev/null @@ -1,22 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -type StreamServer interface { - SendMsg(m interface{}) error - RecvMsg(m interface{}) error -} diff --git a/vendor/github.com/containerd/ttrpc/test.proto b/vendor/github.com/containerd/ttrpc/test.proto deleted file mode 100644 index 0e114d556..000000000 --- a/vendor/github.com/containerd/ttrpc/test.proto +++ /dev/null @@ -1,16 +0,0 @@ -syntax = "proto3"; - -package ttrpc; - -option go_package = "github.com/containerd/ttrpc/internal"; - -message TestPayload { - string foo = 1; - int64 deadline = 2; - string metadata = 3; -} - -message EchoPayload { - int64 seq = 1; - string msg = 2; -} diff --git a/vendor/github.com/containerd/ttrpc/unixcreds_linux.go b/vendor/github.com/containerd/ttrpc/unixcreds_linux.go deleted file mode 100644 index c82c9f9d4..000000000 --- a/vendor/github.com/containerd/ttrpc/unixcreds_linux.go +++ /dev/null @@ -1,105 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package ttrpc - -import ( - "context" - "errors" - "fmt" - "net" - "os" - "syscall" - - "golang.org/x/sys/unix" -) - -type UnixCredentialsFunc func(*unix.Ucred) error - -func (fn UnixCredentialsFunc) Handshake(_ context.Context, conn net.Conn) (net.Conn, interface{}, error) { - uc, err := requireUnixSocket(conn) - if err != nil { - return nil, nil, fmt.Errorf("ttrpc.UnixCredentialsFunc: require unix socket: %w", err) - } - - rs, err := uc.SyscallConn() - if err != nil { - return nil, nil, fmt.Errorf("ttrpc.UnixCredentialsFunc: (net.UnixConn).SyscallConn failed: %w", err) - } - var ( - ucred *unix.Ucred - ucredErr error - ) - if err := rs.Control(func(fd uintptr) { - ucred, ucredErr = unix.GetsockoptUcred(int(fd), unix.SOL_SOCKET, unix.SO_PEERCRED) - }); err != nil { - return nil, nil, fmt.Errorf("ttrpc.UnixCredentialsFunc: (*syscall.RawConn).Control failed: %w", err) - } - - if ucredErr != nil { - return nil, nil, fmt.Errorf("ttrpc.UnixCredentialsFunc: failed to retrieve socket peer credentials: %w", ucredErr) - } - - if err := fn(ucred); err != nil { - return nil, nil, fmt.Errorf("ttrpc.UnixCredentialsFunc: credential check failed: %w", err) - } - - return uc, ucred, nil -} - -// UnixSocketRequireUidGid requires specific *effective* UID/GID, rather than the real UID/GID. -// -// For example, if a daemon binary is owned by the root (UID 0) with SUID bit but running as an -// unprivileged user (UID 1001), the effective UID becomes 0, and the real UID becomes 1001. -// So calling this function with uid=0 allows a connection from effective UID 0 but rejects -// a connection from effective UID 1001. -// -// See socket(7), SO_PEERCRED: "The returned credentials are those that were in effect at the time of the call to connect(2) or socketpair(2)." -func UnixSocketRequireUidGid(uid, gid int) UnixCredentialsFunc { - return func(ucred *unix.Ucred) error { - return requireUidGid(ucred, uid, gid) - } -} - -func UnixSocketRequireRoot() UnixCredentialsFunc { - return UnixSocketRequireUidGid(0, 0) -} - -// UnixSocketRequireSameUser resolves the current effective unix user and returns a -// UnixCredentialsFunc that will validate incoming unix connections against the -// current credentials. -// -// This is useful when using abstract sockets that are accessible by all users. -func UnixSocketRequireSameUser() UnixCredentialsFunc { - euid, egid := os.Geteuid(), os.Getegid() - return UnixSocketRequireUidGid(euid, egid) -} - -func requireUidGid(ucred *unix.Ucred, uid, gid int) error { - if (uid != -1 && uint32(uid) != ucred.Uid) || (gid != -1 && uint32(gid) != ucred.Gid) { - return fmt.Errorf("ttrpc: invalid credentials: %v", syscall.EPERM) - } - return nil -} - -func requireUnixSocket(conn net.Conn) (*net.UnixConn, error) { - uc, ok := conn.(*net.UnixConn) - if !ok { - return nil, errors.New("a unix socket connection is required") - } - - return uc, nil -} diff --git a/vendor/github.com/containerd/typeurl/v2/.gitignore b/vendor/github.com/containerd/typeurl/v2/.gitignore deleted file mode 100644 index d53846778..000000000 --- a/vendor/github.com/containerd/typeurl/v2/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.test -coverage.txt diff --git a/vendor/github.com/containerd/typeurl/v2/LICENSE b/vendor/github.com/containerd/typeurl/v2/LICENSE deleted file mode 100644 index 584149b6e..000000000 --- a/vendor/github.com/containerd/typeurl/v2/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright The containerd Authors - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://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. diff --git a/vendor/github.com/containerd/typeurl/v2/README.md b/vendor/github.com/containerd/typeurl/v2/README.md deleted file mode 100644 index 3098526ab..000000000 --- a/vendor/github.com/containerd/typeurl/v2/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# typeurl - -[![PkgGoDev](https://pkg.go.dev/badge/github.com/containerd/typeurl)](https://pkg.go.dev/github.com/containerd/typeurl) -[![Build Status](https://github.com/containerd/typeurl/workflows/CI/badge.svg)](https://github.com/containerd/typeurl/actions?query=workflow%3ACI) -[![codecov](https://codecov.io/gh/containerd/typeurl/branch/main/graph/badge.svg)](https://codecov.io/gh/containerd/typeurl) -[![Go Report Card](https://goreportcard.com/badge/github.com/containerd/typeurl)](https://goreportcard.com/report/github.com/containerd/typeurl) - -A Go package for managing the registration, marshaling, and unmarshaling of encoded types. - -This package helps when types are sent over a ttrpc/GRPC API and marshaled as a protobuf [Any](https://pkg.go.dev/google.golang.org/protobuf@v1.27.1/types/known/anypb#Any) - -## Project details - -**typeurl** is a containerd sub-project, licensed under the [Apache 2.0 license](./LICENSE). -As a containerd sub-project, you will find the: - * [Project governance](https://github.com/containerd/project/blob/main/GOVERNANCE.md), - * [Maintainers](https://github.com/containerd/project/blob/main/MAINTAINERS), - * and [Contributing guidelines](https://github.com/containerd/project/blob/main/CONTRIBUTING.md) - -information in our [`containerd/project`](https://github.com/containerd/project) repository. - -## Optional - -By default, support for gogoproto is available along side the standard Google -protobuf types. -You can choose to leave gogo support out by using the `!no_gogo` build tag. diff --git a/vendor/github.com/containerd/typeurl/v2/doc.go b/vendor/github.com/containerd/typeurl/v2/doc.go deleted file mode 100644 index c0d0fd205..000000000 --- a/vendor/github.com/containerd/typeurl/v2/doc.go +++ /dev/null @@ -1,83 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package typeurl - -// Package typeurl assists with managing the registration, marshaling, and -// unmarshaling of types encoded as protobuf.Any. -// -// A protobuf.Any is a proto message that can contain any arbitrary data. It -// consists of two components, a TypeUrl and a Value, and its proto definition -// looks like this: -// -// message Any { -// string type_url = 1; -// bytes value = 2; -// } -// -// The TypeUrl is used to distinguish the contents from other proto.Any -// messages. This typeurl library manages these URLs to enable automagic -// marshaling and unmarshaling of the contents. -// -// For example, consider this go struct: -// -// type Foo struct { -// Field1 string -// Field2 string -// } -// -// To use typeurl, types must first be registered. This is typically done in -// the init function -// -// func init() { -// typeurl.Register(&Foo{}, "Foo") -// } -// -// This will register the type Foo with the url path "Foo". The arguments to -// Register are variadic, and are used to construct a url path. Consider this -// example, from the github.com/containerd/containerd/client package: -// -// func init() { -// const prefix = "types.containerd.io" -// // register TypeUrls for commonly marshaled external types -// major := strconv.Itoa(specs.VersionMajor) -// typeurl.Register(&specs.Spec{}, prefix, "opencontainers/runtime-spec", major, "Spec") -// // this function has more Register calls, which are elided. -// } -// -// This registers several types under a more complex url, which ends up mapping -// to `types.containerd.io/opencontainers/runtime-spec/1/Spec` (or some other -// value for major). -// -// Once a type is registered, it can be marshaled to a proto.Any message simply -// by calling `MarshalAny`, like this: -// -// foo := &Foo{Field1: "value1", Field2: "value2"} -// anyFoo, err := typeurl.MarshalAny(foo) -// -// MarshalAny will resolve the correct URL for the type. If the type in -// question implements the proto.Message interface, then it will be marshaled -// as a proto message. Otherwise, it will be marshaled as json. This means that -// typeurl will work on any arbitrary data, whether or not it has a proto -// definition, as long as it can be serialized to json. -// -// To unmarshal, the process is simply inverse: -// -// iface, err := typeurl.UnmarshalAny(anyFoo) -// foo := iface.(*Foo) -// -// The correct type is automatically chosen from the type registry, and the -// returned interface can be cast straight to that type. diff --git a/vendor/github.com/containerd/typeurl/v2/types.go b/vendor/github.com/containerd/typeurl/v2/types.go deleted file mode 100644 index efc405ddd..000000000 --- a/vendor/github.com/containerd/typeurl/v2/types.go +++ /dev/null @@ -1,307 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package typeurl - -import ( - "encoding/json" - "errors" - "fmt" - "path" - "reflect" - "sync" - - "google.golang.org/protobuf/proto" - "google.golang.org/protobuf/reflect/protoregistry" - "google.golang.org/protobuf/types/known/anypb" -) - -var ( - mu sync.RWMutex - registry = make(map[reflect.Type]string) - handlers []handler -) - -type handler interface { - Marshaller(interface{}) func() ([]byte, error) - Unmarshaller(interface{}) func([]byte) error - TypeURL(interface{}) string - GetType(url string) reflect.Type -} - -// Definitions of common error types used throughout typeurl. -// -// These error types are used with errors.Wrap and errors.Wrapf to add context -// to an error. -// -// To detect an error class, use errors.Is() functions to tell whether an -// error is of this type. - -var ( - ErrNotFound = errors.New("not found") -) - -// Any contains an arbitrary protcol buffer message along with its type. -// -// While there is google.golang.org/protobuf/types/known/anypb.Any, -// we'd like to have our own to hide the underlying protocol buffer -// implementations from containerd clients. -// -// https://developers.google.com/protocol-buffers/docs/proto3#any -type Any interface { - // GetTypeUrl returns a URL/resource name that uniquely identifies - // the type of the serialized protocol buffer message. - GetTypeUrl() string - - // GetValue returns a valid serialized protocol buffer of the type that - // GetTypeUrl() indicates. - GetValue() []byte -} - -type anyType struct { - typeURL string - value []byte -} - -func (a *anyType) GetTypeUrl() string { - if a == nil { - return "" - } - return a.typeURL -} - -func (a *anyType) GetValue() []byte { - if a == nil { - return nil - } - return a.value -} - -// Register a type with a base URL for JSON marshaling. When the MarshalAny and -// UnmarshalAny functions are called they will treat the Any type value as JSON. -// To use protocol buffers for handling the Any value the proto.Register -// function should be used instead of this function. -func Register(v interface{}, args ...string) { - var ( - t = tryDereference(v) - p = path.Join(args...) - ) - mu.Lock() - defer mu.Unlock() - if et, ok := registry[t]; ok { - if et != p { - panic(fmt.Errorf("type registered with alternate path %q != %q", et, p)) - } - return - } - registry[t] = p -} - -// TypeURL returns the type url for a registered type. -func TypeURL(v interface{}) (string, error) { - mu.RLock() - u, ok := registry[tryDereference(v)] - mu.RUnlock() - if !ok { - switch t := v.(type) { - case proto.Message: - return string(t.ProtoReflect().Descriptor().FullName()), nil - default: - for _, h := range handlers { - if u := h.TypeURL(v); u != "" { - return u, nil - } - } - return "", fmt.Errorf("type %s: %w", reflect.TypeOf(v), ErrNotFound) - } - } - return u, nil -} - -// Is returns true if the type of the Any is the same as v. -func Is(any Any, v interface{}) bool { - if any == nil { - return false - } - // call to check that v is a pointer - tryDereference(v) - url, err := TypeURL(v) - if err != nil { - return false - } - return any.GetTypeUrl() == url -} - -// MarshalAny marshals the value v into an any with the correct TypeUrl. -// If the provided object is already a proto.Any message, then it will be -// returned verbatim. If it is of type proto.Message, it will be marshaled as a -// protocol buffer. Otherwise, the object will be marshaled to json. -func MarshalAny(v interface{}) (Any, error) { - var marshal func(v interface{}) ([]byte, error) - switch t := v.(type) { - case Any: - // avoid reserializing the type if we have an any. - return t, nil - case proto.Message: - marshal = func(v interface{}) ([]byte, error) { - return proto.Marshal(t) - } - default: - for _, h := range handlers { - if m := h.Marshaller(v); m != nil { - marshal = func(v interface{}) ([]byte, error) { - return m() - } - break - } - } - - if marshal == nil { - marshal = json.Marshal - } - } - - url, err := TypeURL(v) - if err != nil { - return nil, err - } - - data, err := marshal(v) - if err != nil { - return nil, err - } - return &anyType{ - typeURL: url, - value: data, - }, nil -} - -// UnmarshalAny unmarshals the any type into a concrete type. -func UnmarshalAny(any Any) (interface{}, error) { - return UnmarshalByTypeURL(any.GetTypeUrl(), any.GetValue()) -} - -// UnmarshalByTypeURL unmarshals the given type and value to into a concrete type. -func UnmarshalByTypeURL(typeURL string, value []byte) (interface{}, error) { - return unmarshal(typeURL, value, nil) -} - -// UnmarshalTo unmarshals the any type into a concrete type passed in the out -// argument. It is identical to UnmarshalAny, but lets clients provide a -// destination type through the out argument. -func UnmarshalTo(any Any, out interface{}) error { - return UnmarshalToByTypeURL(any.GetTypeUrl(), any.GetValue(), out) -} - -// UnmarshalToByTypeURL unmarshals the given type and value into a concrete type passed -// in the out argument. It is identical to UnmarshalByTypeURL, but lets clients -// provide a destination type through the out argument. -func UnmarshalToByTypeURL(typeURL string, value []byte, out interface{}) error { - _, err := unmarshal(typeURL, value, out) - return err -} - -// MarshalProto converts typeurl.Any to google.golang.org/protobuf/types/known/anypb.Any. -func MarshalProto(from Any) *anypb.Any { - if from == nil { - return nil - } - - if pbany, ok := from.(*anypb.Any); ok { - return pbany - } - - return &anypb.Any{ - TypeUrl: from.GetTypeUrl(), - Value: from.GetValue(), - } -} - -// MarshalAnyToProto converts an arbitrary interface to google.golang.org/protobuf/types/known/anypb.Any. -func MarshalAnyToProto(from interface{}) (*anypb.Any, error) { - anyType, err := MarshalAny(from) - if err != nil { - return nil, err - } - return MarshalProto(anyType), nil -} - -func unmarshal(typeURL string, value []byte, v interface{}) (interface{}, error) { - t, err := getTypeByUrl(typeURL) - if err != nil { - return nil, err - } - - if v == nil { - v = reflect.New(t).Interface() - } else { - // Validate interface type provided by client - vURL, err := TypeURL(v) - if err != nil { - return nil, err - } - if typeURL != vURL { - return nil, fmt.Errorf("can't unmarshal type %q to output %q", typeURL, vURL) - } - } - - pm, ok := v.(proto.Message) - if ok { - return v, proto.Unmarshal(value, pm) - } - - for _, h := range handlers { - if unmarshal := h.Unmarshaller(v); unmarshal != nil { - return v, unmarshal(value) - } - } - - // fallback to json unmarshaller - return v, json.Unmarshal(value, v) -} - -func getTypeByUrl(url string) (reflect.Type, error) { - mu.RLock() - for t, u := range registry { - if u == url { - mu.RUnlock() - return t, nil - } - } - mu.RUnlock() - mt, err := protoregistry.GlobalTypes.FindMessageByURL(url) - if err != nil { - if errors.Is(err, protoregistry.NotFound) { - for _, h := range handlers { - if t := h.GetType(url); t != nil { - return t, nil - } - } - } - return nil, fmt.Errorf("type with url %s: %w", url, ErrNotFound) - } - empty := mt.New().Interface() - return reflect.TypeOf(empty).Elem(), nil -} - -func tryDereference(v interface{}) reflect.Type { - t := reflect.TypeOf(v) - if t.Kind() == reflect.Ptr { - // require check of pointer but dereference to register - return t.Elem() - } - panic("v is not a pointer to a type") -} diff --git a/vendor/github.com/containerd/typeurl/v2/types_gogo.go b/vendor/github.com/containerd/typeurl/v2/types_gogo.go deleted file mode 100644 index fa293323b..000000000 --- a/vendor/github.com/containerd/typeurl/v2/types_gogo.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build !no_gogo - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package typeurl - -import ( - "reflect" - - gogoproto "github.com/gogo/protobuf/proto" -) - -func init() { - handlers = append(handlers, gogoHandler{}) -} - -type gogoHandler struct{} - -func (gogoHandler) Marshaller(v interface{}) func() ([]byte, error) { - pm, ok := v.(gogoproto.Message) - if !ok { - return nil - } - return func() ([]byte, error) { - return gogoproto.Marshal(pm) - } -} - -func (gogoHandler) Unmarshaller(v interface{}) func([]byte) error { - pm, ok := v.(gogoproto.Message) - if !ok { - return nil - } - - return func(dt []byte) error { - return gogoproto.Unmarshal(dt, pm) - } -} - -func (gogoHandler) TypeURL(v interface{}) string { - pm, ok := v.(gogoproto.Message) - if !ok { - return "" - } - return gogoproto.MessageName(pm) -} - -func (gogoHandler) GetType(url string) reflect.Type { - t := gogoproto.MessageType(url) - if t == nil { - return nil - } - return t.Elem() -} diff --git a/vendor/github.com/coreos/go-systemd/v22/LICENSE b/vendor/github.com/coreos/go-systemd/v22/LICENSE deleted file mode 100644 index 37ec93a14..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ -Apache License -Version 2.0, January 2004 -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -You must give any other recipients of the Work or Derivative Works a copy of -this License; and -You must cause any modified files to carry prominent notices stating that You -changed the files; and -You must retain, in the Source form of any Derivative Works that You distribute, -all copyright, patent, trademark, and attribution notices from the Source form -of the Work, excluding those notices that do not pertain to any part of the -Derivative Works; and -If the Work includes a "NOTICE" text file as part of its distribution, then any -Derivative Works that You distribute must include a readable copy of the -attribution notices contained within such NOTICE file, excluding those notices -that do not pertain to any part of the Derivative Works, in at least one of the -following places: within a NOTICE text file distributed as part of the -Derivative Works; within the Source form or documentation, if provided along -with the Derivative Works; or, within a display generated by the Derivative -Works, if and wherever such third-party notices normally appear. The contents of -the NOTICE file are for informational purposes only and do not modify the -License. You may add Your own attribution notices within Derivative Works that -You distribute, alongside or as an addendum to the NOTICE text from the Work, -provided that such additional attribution notices cannot be construed as -modifying the License. -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, -NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -APPENDIX: How to apply the Apache License to your work - -To apply the Apache License to your work, attach the following boilerplate -notice, with the fields enclosed by brackets "[]" replaced with your own -identifying information. (Don't include the brackets!) The text should be -enclosed in the appropriate comment syntax for the file format. We also -recommend that a file or class name and description of purpose be included on -the same "printed page" as the copyright notice for easier identification within -third-party archives. - - Copyright [yyyy] [name of copyright owner] - - 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. diff --git a/vendor/github.com/coreos/go-systemd/v22/NOTICE b/vendor/github.com/coreos/go-systemd/v22/NOTICE deleted file mode 100644 index 23a0ada2f..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -CoreOS Project -Copyright 2018 CoreOS, Inc - -This product includes software developed at CoreOS, Inc. -(http://www.coreos.com/). diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go b/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go deleted file mode 100644 index 147f756fe..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/dbus.go +++ /dev/null @@ -1,266 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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. - -// Integration with the systemd D-Bus API. See http://www.freedesktop.org/wiki/Software/systemd/dbus/ -package dbus - -import ( - "context" - "encoding/hex" - "fmt" - "os" - "strconv" - "strings" - "sync" - - "github.com/godbus/dbus/v5" -) - -const ( - alpha = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ` - num = `0123456789` - alphanum = alpha + num - signalBuffer = 100 -) - -// needsEscape checks whether a byte in a potential dbus ObjectPath needs to be escaped -func needsEscape(i int, b byte) bool { - // Escape everything that is not a-z-A-Z-0-9 - // Also escape 0-9 if it's the first character - return strings.IndexByte(alphanum, b) == -1 || - (i == 0 && strings.IndexByte(num, b) != -1) -} - -// PathBusEscape sanitizes a constituent string of a dbus ObjectPath using the -// rules that systemd uses for serializing special characters. -func PathBusEscape(path string) string { - // Special case the empty string - if len(path) == 0 { - return "_" - } - n := []byte{} - for i := 0; i < len(path); i++ { - c := path[i] - if needsEscape(i, c) { - e := fmt.Sprintf("_%x", c) - n = append(n, []byte(e)...) - } else { - n = append(n, c) - } - } - return string(n) -} - -// pathBusUnescape is the inverse of PathBusEscape. -func pathBusUnescape(path string) string { - if path == "_" { - return "" - } - n := []byte{} - for i := 0; i < len(path); i++ { - c := path[i] - if c == '_' && i+2 < len(path) { - res, err := hex.DecodeString(path[i+1 : i+3]) - if err == nil { - n = append(n, res...) - } - i += 2 - } else { - n = append(n, c) - } - } - return string(n) -} - -// Conn is a connection to systemd's dbus endpoint. -type Conn struct { - // sysconn/sysobj are only used to call dbus methods - sysconn *dbus.Conn - sysobj dbus.BusObject - - // sigconn/sigobj are only used to receive dbus signals - sigconn *dbus.Conn - sigobj dbus.BusObject - - jobListener struct { - jobs map[dbus.ObjectPath]chan<- string - sync.Mutex - } - subStateSubscriber struct { - updateCh chan<- *SubStateUpdate - errCh chan<- error - sync.Mutex - ignore map[dbus.ObjectPath]int64 - cleanIgnore int64 - } - propertiesSubscriber struct { - updateCh chan<- *PropertiesUpdate - errCh chan<- error - sync.Mutex - } -} - -// Deprecated: use NewWithContext instead. -func New() (*Conn, error) { - return NewWithContext(context.Background()) -} - -// NewWithContext establishes a connection to any available bus and authenticates. -// Callers should call Close() when done with the connection. -func NewWithContext(ctx context.Context) (*Conn, error) { - conn, err := NewSystemConnectionContext(ctx) - if err != nil && os.Geteuid() == 0 { - return NewSystemdConnectionContext(ctx) - } - return conn, err -} - -// Deprecated: use NewSystemConnectionContext instead. -func NewSystemConnection() (*Conn, error) { - return NewSystemConnectionContext(context.Background()) -} - -// NewSystemConnectionContext establishes a connection to the system bus and authenticates. -// Callers should call Close() when done with the connection. -func NewSystemConnectionContext(ctx context.Context) (*Conn, error) { - return NewConnection(func() (*dbus.Conn, error) { - return dbusAuthHelloConnection(ctx, dbus.SystemBusPrivate) - }) -} - -// Deprecated: use NewUserConnectionContext instead. -func NewUserConnection() (*Conn, error) { - return NewUserConnectionContext(context.Background()) -} - -// NewUserConnectionContext establishes a connection to the session bus and -// authenticates. This can be used to connect to systemd user instances. -// Callers should call Close() when done with the connection. -func NewUserConnectionContext(ctx context.Context) (*Conn, error) { - return NewConnection(func() (*dbus.Conn, error) { - return dbusAuthHelloConnection(ctx, dbus.SessionBusPrivate) - }) -} - -// Deprecated: use NewSystemdConnectionContext instead. -func NewSystemdConnection() (*Conn, error) { - return NewSystemdConnectionContext(context.Background()) -} - -// NewSystemdConnectionContext establishes a private, direct connection to systemd. -// This can be used for communicating with systemd without a dbus daemon. -// Callers should call Close() when done with the connection. -func NewSystemdConnectionContext(ctx context.Context) (*Conn, error) { - return NewConnection(func() (*dbus.Conn, error) { - // We skip Hello when talking directly to systemd. - return dbusAuthConnection(ctx, func(opts ...dbus.ConnOption) (*dbus.Conn, error) { - return dbus.Dial("unix:path=/run/systemd/private", opts...) - }) - }) -} - -// Close closes an established connection. -func (c *Conn) Close() { - c.sysconn.Close() - c.sigconn.Close() -} - -// Connected returns whether conn is connected -func (c *Conn) Connected() bool { - return c.sysconn.Connected() && c.sigconn.Connected() -} - -// NewConnection establishes a connection to a bus using a caller-supplied function. -// This allows connecting to remote buses through a user-supplied mechanism. -// The supplied function may be called multiple times, and should return independent connections. -// The returned connection must be fully initialised: the org.freedesktop.DBus.Hello call must have succeeded, -// and any authentication should be handled by the function. -func NewConnection(dialBus func() (*dbus.Conn, error)) (*Conn, error) { - sysconn, err := dialBus() - if err != nil { - return nil, err - } - - sigconn, err := dialBus() - if err != nil { - sysconn.Close() - return nil, err - } - - c := &Conn{ - sysconn: sysconn, - sysobj: systemdObject(sysconn), - sigconn: sigconn, - sigobj: systemdObject(sigconn), - } - - c.subStateSubscriber.ignore = make(map[dbus.ObjectPath]int64) - c.jobListener.jobs = make(map[dbus.ObjectPath]chan<- string) - - // Setup the listeners on jobs so that we can get completions - c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal', interface='org.freedesktop.systemd1.Manager', member='JobRemoved'") - - c.dispatch() - return c, nil -} - -// GetManagerProperty returns the value of a property on the org.freedesktop.systemd1.Manager -// interface. The value is returned in its string representation, as defined at -// https://developer.gnome.org/glib/unstable/gvariant-text.html. -func (c *Conn) GetManagerProperty(prop string) (string, error) { - variant, err := c.sysobj.GetProperty("org.freedesktop.systemd1.Manager." + prop) - if err != nil { - return "", err - } - return variant.String(), nil -} - -func dbusAuthConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) { - conn, err := createBus(dbus.WithContext(ctx)) - if err != nil { - return nil, err - } - - // Only use EXTERNAL method, and hardcode the uid (not username) - // to avoid a username lookup (which requires a dynamically linked - // libc) - methods := []dbus.Auth{dbus.AuthExternal(strconv.Itoa(os.Getuid()))} - - err = conn.Auth(methods) - if err != nil { - conn.Close() - return nil, err - } - - return conn, nil -} - -func dbusAuthHelloConnection(ctx context.Context, createBus func(opts ...dbus.ConnOption) (*dbus.Conn, error)) (*dbus.Conn, error) { - conn, err := dbusAuthConnection(ctx, createBus) - if err != nil { - return nil, err - } - - if err = conn.Hello(); err != nil { - conn.Close() - return nil, err - } - - return conn, nil -} - -func systemdObject(conn *dbus.Conn) dbus.BusObject { - return conn.Object("org.freedesktop.systemd1", dbus.ObjectPath("/org/freedesktop/systemd1")) -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go b/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go deleted file mode 100644 index 074148cb4..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/methods.go +++ /dev/null @@ -1,864 +0,0 @@ -// Copyright 2015, 2018 CoreOS, Inc. -// -// 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 dbus - -import ( - "context" - "errors" - "fmt" - "path" - "strconv" - - "github.com/godbus/dbus/v5" -) - -// Who can be used to specify which process to kill in the unit via the KillUnitWithTarget API -type Who string - -const ( - // All sends the signal to all processes in the unit - All Who = "all" - // Main sends the signal to the main process of the unit - Main Who = "main" - // Control sends the signal to the control process of the unit - Control Who = "control" -) - -func (c *Conn) jobComplete(signal *dbus.Signal) { - var id uint32 - var job dbus.ObjectPath - var unit string - var result string - dbus.Store(signal.Body, &id, &job, &unit, &result) - c.jobListener.Lock() - out, ok := c.jobListener.jobs[job] - if ok { - out <- result - delete(c.jobListener.jobs, job) - } - c.jobListener.Unlock() -} - -func (c *Conn) startJob(ctx context.Context, ch chan<- string, job string, args ...interface{}) (int, error) { - if ch != nil { - c.jobListener.Lock() - defer c.jobListener.Unlock() - } - - var p dbus.ObjectPath - err := c.sysobj.CallWithContext(ctx, job, 0, args...).Store(&p) - if err != nil { - return 0, err - } - - if ch != nil { - c.jobListener.jobs[p] = ch - } - - // ignore error since 0 is fine if conversion fails - jobID, _ := strconv.Atoi(path.Base(string(p))) - - return jobID, nil -} - -// Deprecated: use StartUnitContext instead. -func (c *Conn) StartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.StartUnitContext(context.Background(), name, mode, ch) -} - -// StartUnitContext enqueues a start job and depending jobs, if any (unless otherwise -// specified by the mode string). -// -// Takes the unit to activate, plus a mode string. The mode needs to be one of -// replace, fail, isolate, ignore-dependencies, ignore-requirements. If -// "replace" the call will start the unit and its dependencies, possibly -// replacing already queued jobs that conflict with this. If "fail" the call -// will start the unit and its dependencies, but will fail if this would change -// an already queued job. If "isolate" the call will start the unit in question -// and terminate all units that aren't dependencies of it. If -// "ignore-dependencies" it will start a unit but ignore all its dependencies. -// If "ignore-requirements" it will start a unit but only ignore the -// requirement dependencies. It is not recommended to make use of the latter -// two options. -// -// If the provided channel is non-nil, a result string will be sent to it upon -// job completion: one of done, canceled, timeout, failed, dependency, skipped. -// done indicates successful execution of a job. canceled indicates that a job -// has been canceled before it finished execution. timeout indicates that the -// job timeout was reached. failed indicates that the job failed. dependency -// indicates that a job this job has been depending on failed and the job hence -// has been removed too. skipped indicates that a job was skipped because it -// didn't apply to the units current state. -// -// If no error occurs, the ID of the underlying systemd job will be returned. There -// does exist the possibility for no error to be returned, but for the returned job -// ID to be 0. In this case, the actual underlying ID is not 0 and this datapoint -// should not be considered authoritative. -// -// If an error does occur, it will be returned to the user alongside a job ID of 0. -func (c *Conn) StartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartUnit", name, mode) -} - -// Deprecated: use StopUnitContext instead. -func (c *Conn) StopUnit(name string, mode string, ch chan<- string) (int, error) { - return c.StopUnitContext(context.Background(), name, mode, ch) -} - -// StopUnitContext is similar to StartUnitContext, but stops the specified unit -// rather than starting it. -func (c *Conn) StopUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StopUnit", name, mode) -} - -// Deprecated: use ReloadUnitContext instead. -func (c *Conn) ReloadUnit(name string, mode string, ch chan<- string) (int, error) { - return c.ReloadUnitContext(context.Background(), name, mode, ch) -} - -// ReloadUnitContext reloads a unit. Reloading is done only if the unit -// is already running, and fails otherwise. -func (c *Conn) ReloadUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadUnit", name, mode) -} - -// Deprecated: use RestartUnitContext instead. -func (c *Conn) RestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.RestartUnitContext(context.Background(), name, mode, ch) -} - -// RestartUnitContext restarts a service. If a service is restarted that isn't -// running it will be started. -func (c *Conn) RestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.RestartUnit", name, mode) -} - -// Deprecated: use TryRestartUnitContext instead. -func (c *Conn) TryRestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.TryRestartUnitContext(context.Background(), name, mode, ch) -} - -// TryRestartUnitContext is like RestartUnitContext, except that a service that -// isn't running is not affected by the restart. -func (c *Conn) TryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.TryRestartUnit", name, mode) -} - -// Deprecated: use ReloadOrRestartUnitContext instead. -func (c *Conn) ReloadOrRestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.ReloadOrRestartUnitContext(context.Background(), name, mode, ch) -} - -// ReloadOrRestartUnitContext attempts a reload if the unit supports it and use -// a restart otherwise. -func (c *Conn) ReloadOrRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrRestartUnit", name, mode) -} - -// Deprecated: use ReloadOrTryRestartUnitContext instead. -func (c *Conn) ReloadOrTryRestartUnit(name string, mode string, ch chan<- string) (int, error) { - return c.ReloadOrTryRestartUnitContext(context.Background(), name, mode, ch) -} - -// ReloadOrTryRestartUnitContext attempts a reload if the unit supports it, -// and use a "Try" flavored restart otherwise. -func (c *Conn) ReloadOrTryRestartUnitContext(ctx context.Context, name string, mode string, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.ReloadOrTryRestartUnit", name, mode) -} - -// Deprecated: use StartTransientUnitContext instead. -func (c *Conn) StartTransientUnit(name string, mode string, properties []Property, ch chan<- string) (int, error) { - return c.StartTransientUnitContext(context.Background(), name, mode, properties, ch) -} - -// StartTransientUnitContext may be used to create and start a transient unit, which -// will be released as soon as it is not running or referenced anymore or the -// system is rebooted. name is the unit name including suffix, and must be -// unique. mode is the same as in StartUnitContext, properties contains properties -// of the unit. -func (c *Conn) StartTransientUnitContext(ctx context.Context, name string, mode string, properties []Property, ch chan<- string) (int, error) { - return c.startJob(ctx, ch, "org.freedesktop.systemd1.Manager.StartTransientUnit", name, mode, properties, make([]PropertyCollection, 0)) -} - -// Deprecated: use KillUnitContext instead. -func (c *Conn) KillUnit(name string, signal int32) { - c.KillUnitContext(context.Background(), name, signal) -} - -// KillUnitContext takes the unit name and a UNIX signal number to send. -// All of the unit's processes are killed. -func (c *Conn) KillUnitContext(ctx context.Context, name string, signal int32) { - c.KillUnitWithTarget(ctx, name, All, signal) -} - -// KillUnitWithTarget is like KillUnitContext, but allows you to specify which -// process in the unit to send the signal to. -func (c *Conn) KillUnitWithTarget(ctx context.Context, name string, target Who, signal int32) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.KillUnit", 0, name, string(target), signal).Store() -} - -// Deprecated: use ResetFailedUnitContext instead. -func (c *Conn) ResetFailedUnit(name string) error { - return c.ResetFailedUnitContext(context.Background(), name) -} - -// ResetFailedUnitContext resets the "failed" state of a specific unit. -func (c *Conn) ResetFailedUnitContext(ctx context.Context, name string) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ResetFailedUnit", 0, name).Store() -} - -// Deprecated: use SystemStateContext instead. -func (c *Conn) SystemState() (*Property, error) { - return c.SystemStateContext(context.Background()) -} - -// SystemStateContext returns the systemd state. Equivalent to -// systemctl is-system-running. -func (c *Conn) SystemStateContext(ctx context.Context) (*Property, error) { - var err error - var prop dbus.Variant - - obj := c.sysconn.Object("org.freedesktop.systemd1", "/org/freedesktop/systemd1") - err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, "org.freedesktop.systemd1.Manager", "SystemState").Store(&prop) - if err != nil { - return nil, err - } - - return &Property{Name: "SystemState", Value: prop}, nil -} - -// getProperties takes the unit path and returns all of its dbus object properties, for the given dbus interface. -func (c *Conn) getProperties(ctx context.Context, path dbus.ObjectPath, dbusInterface string) (map[string]interface{}, error) { - var err error - var props map[string]dbus.Variant - - if !path.IsValid() { - return nil, fmt.Errorf("invalid unit name: %v", path) - } - - obj := c.sysconn.Object("org.freedesktop.systemd1", path) - err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.GetAll", 0, dbusInterface).Store(&props) - if err != nil { - return nil, err - } - - out := make(map[string]interface{}, len(props)) - for k, v := range props { - out[k] = v.Value() - } - - return out, nil -} - -// Deprecated: use GetUnitPropertiesContext instead. -func (c *Conn) GetUnitProperties(unit string) (map[string]interface{}, error) { - return c.GetUnitPropertiesContext(context.Background(), unit) -} - -// GetUnitPropertiesContext takes the (unescaped) unit name and returns all of -// its dbus object properties. -func (c *Conn) GetUnitPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) { - path := unitPath(unit) - return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit") -} - -// Deprecated: use GetUnitPathPropertiesContext instead. -func (c *Conn) GetUnitPathProperties(path dbus.ObjectPath) (map[string]interface{}, error) { - return c.GetUnitPathPropertiesContext(context.Background(), path) -} - -// GetUnitPathPropertiesContext takes the (escaped) unit path and returns all -// of its dbus object properties. -func (c *Conn) GetUnitPathPropertiesContext(ctx context.Context, path dbus.ObjectPath) (map[string]interface{}, error) { - return c.getProperties(ctx, path, "org.freedesktop.systemd1.Unit") -} - -// Deprecated: use GetAllPropertiesContext instead. -func (c *Conn) GetAllProperties(unit string) (map[string]interface{}, error) { - return c.GetAllPropertiesContext(context.Background(), unit) -} - -// GetAllPropertiesContext takes the (unescaped) unit name and returns all of -// its dbus object properties. -func (c *Conn) GetAllPropertiesContext(ctx context.Context, unit string) (map[string]interface{}, error) { - path := unitPath(unit) - return c.getProperties(ctx, path, "") -} - -func (c *Conn) getProperty(ctx context.Context, unit string, dbusInterface string, propertyName string) (*Property, error) { - var err error - var prop dbus.Variant - - path := unitPath(unit) - if !path.IsValid() { - return nil, errors.New("invalid unit name: " + unit) - } - - obj := c.sysconn.Object("org.freedesktop.systemd1", path) - err = obj.CallWithContext(ctx, "org.freedesktop.DBus.Properties.Get", 0, dbusInterface, propertyName).Store(&prop) - if err != nil { - return nil, err - } - - return &Property{Name: propertyName, Value: prop}, nil -} - -// Deprecated: use GetUnitPropertyContext instead. -func (c *Conn) GetUnitProperty(unit string, propertyName string) (*Property, error) { - return c.GetUnitPropertyContext(context.Background(), unit, propertyName) -} - -// GetUnitPropertyContext takes an (unescaped) unit name, and a property name, -// and returns the property value. -func (c *Conn) GetUnitPropertyContext(ctx context.Context, unit string, propertyName string) (*Property, error) { - return c.getProperty(ctx, unit, "org.freedesktop.systemd1.Unit", propertyName) -} - -// Deprecated: use GetServicePropertyContext instead. -func (c *Conn) GetServiceProperty(service string, propertyName string) (*Property, error) { - return c.GetServicePropertyContext(context.Background(), service, propertyName) -} - -// GetServiceProperty returns property for given service name and property name. -func (c *Conn) GetServicePropertyContext(ctx context.Context, service string, propertyName string) (*Property, error) { - return c.getProperty(ctx, service, "org.freedesktop.systemd1.Service", propertyName) -} - -// Deprecated: use GetUnitTypePropertiesContext instead. -func (c *Conn) GetUnitTypeProperties(unit string, unitType string) (map[string]interface{}, error) { - return c.GetUnitTypePropertiesContext(context.Background(), unit, unitType) -} - -// GetUnitTypePropertiesContext returns the extra properties for a unit, specific to the unit type. -// Valid values for unitType: Service, Socket, Target, Device, Mount, Automount, Snapshot, Timer, Swap, Path, Slice, Scope. -// Returns "dbus.Error: Unknown interface" error if the unitType is not the correct type of the unit. -func (c *Conn) GetUnitTypePropertiesContext(ctx context.Context, unit string, unitType string) (map[string]interface{}, error) { - path := unitPath(unit) - return c.getProperties(ctx, path, "org.freedesktop.systemd1."+unitType) -} - -// Deprecated: use SetUnitPropertiesContext instead. -func (c *Conn) SetUnitProperties(name string, runtime bool, properties ...Property) error { - return c.SetUnitPropertiesContext(context.Background(), name, runtime, properties...) -} - -// SetUnitPropertiesContext may be used to modify certain unit properties at runtime. -// Not all properties may be changed at runtime, but many resource management -// settings (primarily those in systemd.cgroup(5)) may. The changes are applied -// instantly, and stored on disk for future boots, unless runtime is true, in which -// case the settings only apply until the next reboot. name is the name of the unit -// to modify. properties are the settings to set, encoded as an array of property -// name and value pairs. -func (c *Conn) SetUnitPropertiesContext(ctx context.Context, name string, runtime bool, properties ...Property) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.SetUnitProperties", 0, name, runtime, properties).Store() -} - -// Deprecated: use GetUnitTypePropertyContext instead. -func (c *Conn) GetUnitTypeProperty(unit string, unitType string, propertyName string) (*Property, error) { - return c.GetUnitTypePropertyContext(context.Background(), unit, unitType, propertyName) -} - -// GetUnitTypePropertyContext takes a property name, a unit name, and a unit type, -// and returns a property value. For valid values of unitType, see GetUnitTypePropertiesContext. -func (c *Conn) GetUnitTypePropertyContext(ctx context.Context, unit string, unitType string, propertyName string) (*Property, error) { - return c.getProperty(ctx, unit, "org.freedesktop.systemd1."+unitType, propertyName) -} - -type UnitStatus struct { - Name string // The primary unit name as string - Description string // The human readable description string - LoadState string // The load state (i.e. whether the unit file has been loaded successfully) - ActiveState string // The active state (i.e. whether the unit is currently started or not) - SubState string // The sub state (a more fine-grained version of the active state that is specific to the unit type, which the active state is not) - Followed string // A unit that is being followed in its state by this unit, if there is any, otherwise the empty string. - Path dbus.ObjectPath // The unit object path - JobId uint32 // If there is a job queued for the job unit the numeric job id, 0 otherwise - JobType string // The job type as string - JobPath dbus.ObjectPath // The job object path -} - -type storeFunc func(retvalues ...interface{}) error - -func (c *Conn) listUnitsInternal(f storeFunc) ([]UnitStatus, error) { - result := make([][]interface{}, 0) - err := f(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - status := make([]UnitStatus, len(result)) - statusInterface := make([]interface{}, len(status)) - for i := range status { - statusInterface[i] = &status[i] - } - - err = dbus.Store(resultInterface, statusInterface...) - if err != nil { - return nil, err - } - - return status, nil -} - -// GetUnitByPID returns the unit object path of the unit a process ID -// belongs to. It takes a UNIX PID and returns the object path. The PID must -// refer to an existing system process -func (c *Conn) GetUnitByPID(ctx context.Context, pid uint32) (dbus.ObjectPath, error) { - var result dbus.ObjectPath - - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.GetUnitByPID", 0, pid).Store(&result) - - return result, err -} - -// GetUnitNameByPID returns the name of the unit a process ID belongs to. It -// takes a UNIX PID and returns the object path. The PID must refer to an -// existing system process -func (c *Conn) GetUnitNameByPID(ctx context.Context, pid uint32) (string, error) { - path, err := c.GetUnitByPID(ctx, pid) - if err != nil { - return "", err - } - - return unitName(path), nil -} - -// Deprecated: use ListUnitsContext instead. -func (c *Conn) ListUnits() ([]UnitStatus, error) { - return c.ListUnitsContext(context.Background()) -} - -// ListUnitsContext returns an array with all currently loaded units. Note that -// units may be known by multiple names at the same time, and hence there might -// be more unit names loaded than actual units behind them. -// Also note that a unit is only loaded if it is active and/or enabled. -// Units that are both disabled and inactive will thus not be returned. -func (c *Conn) ListUnitsContext(ctx context.Context) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnits", 0).Store) -} - -// Deprecated: use ListUnitsFilteredContext instead. -func (c *Conn) ListUnitsFiltered(states []string) ([]UnitStatus, error) { - return c.ListUnitsFilteredContext(context.Background(), states) -} - -// ListUnitsFilteredContext returns an array with units filtered by state. -// It takes a list of units' statuses to filter. -func (c *Conn) ListUnitsFilteredContext(ctx context.Context, states []string) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsFiltered", 0, states).Store) -} - -// Deprecated: use ListUnitsByPatternsContext instead. -func (c *Conn) ListUnitsByPatterns(states []string, patterns []string) ([]UnitStatus, error) { - return c.ListUnitsByPatternsContext(context.Background(), states, patterns) -} - -// ListUnitsByPatternsContext returns an array with units. -// It takes a list of units' statuses and names to filter. -// Note that units may be known by multiple names at the same time, -// and hence there might be more unit names loaded than actual units behind them. -func (c *Conn) ListUnitsByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByPatterns", 0, states, patterns).Store) -} - -// Deprecated: use ListUnitsByNamesContext instead. -func (c *Conn) ListUnitsByNames(units []string) ([]UnitStatus, error) { - return c.ListUnitsByNamesContext(context.Background(), units) -} - -// ListUnitsByNamesContext returns an array with units. It takes a list of units' -// names and returns an UnitStatus array. Comparing to ListUnitsByPatternsContext -// method, this method returns statuses even for inactive or non-existing -// units. Input array should contain exact unit names, but not patterns. -// -// Requires systemd v230 or higher. -func (c *Conn) ListUnitsByNamesContext(ctx context.Context, units []string) ([]UnitStatus, error) { - return c.listUnitsInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitsByNames", 0, units).Store) -} - -type UnitFile struct { - Path string - Type string -} - -func (c *Conn) listUnitFilesInternal(f storeFunc) ([]UnitFile, error) { - result := make([][]interface{}, 0) - err := f(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - files := make([]UnitFile, len(result)) - fileInterface := make([]interface{}, len(files)) - for i := range files { - fileInterface[i] = &files[i] - } - - err = dbus.Store(resultInterface, fileInterface...) - if err != nil { - return nil, err - } - - return files, nil -} - -// Deprecated: use ListUnitFilesContext instead. -func (c *Conn) ListUnitFiles() ([]UnitFile, error) { - return c.ListUnitFilesContext(context.Background()) -} - -// ListUnitFiles returns an array of all available units on disk. -func (c *Conn) ListUnitFilesContext(ctx context.Context) ([]UnitFile, error) { - return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFiles", 0).Store) -} - -// Deprecated: use ListUnitFilesByPatternsContext instead. -func (c *Conn) ListUnitFilesByPatterns(states []string, patterns []string) ([]UnitFile, error) { - return c.ListUnitFilesByPatternsContext(context.Background(), states, patterns) -} - -// ListUnitFilesByPatternsContext returns an array of all available units on disk matched the patterns. -func (c *Conn) ListUnitFilesByPatternsContext(ctx context.Context, states []string, patterns []string) ([]UnitFile, error) { - return c.listUnitFilesInternal(c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListUnitFilesByPatterns", 0, states, patterns).Store) -} - -type LinkUnitFileChange EnableUnitFileChange - -// Deprecated: use LinkUnitFilesContext instead. -func (c *Conn) LinkUnitFiles(files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { - return c.LinkUnitFilesContext(context.Background(), files, runtime, force) -} - -// LinkUnitFilesContext links unit files (that are located outside of the -// usual unit search paths) into the unit search path. -// -// It takes a list of absolute paths to unit files to link and two -// booleans. -// -// The first boolean controls whether the unit shall be -// enabled for runtime only (true, /run), or persistently (false, -// /etc). -// -// The second controls whether symlinks pointing to other units shall -// be replaced if necessary. -// -// This call returns a list of the changes made. The list consists of -// structures with three strings: the type of the change (one of symlink -// or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) LinkUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]LinkUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.LinkUnitFiles", 0, files, runtime, force).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]LinkUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -// Deprecated: use EnableUnitFilesContext instead. -func (c *Conn) EnableUnitFiles(files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { - return c.EnableUnitFilesContext(context.Background(), files, runtime, force) -} - -// EnableUnitFilesContext may be used to enable one or more units in the system -// (by creating symlinks to them in /etc or /run). -// -// It takes a list of unit files to enable (either just file names or full -// absolute paths if the unit files are residing outside the usual unit -// search paths), and two booleans: the first controls whether the unit shall -// be enabled for runtime only (true, /run), or persistently (false, /etc). -// The second one controls whether symlinks pointing to other units shall -// be replaced if necessary. -// -// This call returns one boolean and an array with the changes made. The -// boolean signals whether the unit files contained any enablement -// information (i.e. an [Install]) section. The changes list consists of -// structures with three strings: the type of the change (one of symlink -// or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) EnableUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) (bool, []EnableUnitFileChange, error) { - var carries_install_info bool - - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.EnableUnitFiles", 0, files, runtime, force).Store(&carries_install_info, &result) - if err != nil { - return false, nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]EnableUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return false, nil, err - } - - return carries_install_info, changes, nil -} - -type EnableUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use DisableUnitFilesContext instead. -func (c *Conn) DisableUnitFiles(files []string, runtime bool) ([]DisableUnitFileChange, error) { - return c.DisableUnitFilesContext(context.Background(), files, runtime) -} - -// DisableUnitFilesContext may be used to disable one or more units in the -// system (by removing symlinks to them from /etc or /run). -// -// It takes a list of unit files to disable (either just file names or full -// absolute paths if the unit files are residing outside the usual unit -// search paths), and one boolean: whether the unit was enabled for runtime -// only (true, /run), or persistently (false, /etc). -// -// This call returns an array with the changes made. The changes list -// consists of structures with three strings: the type of the change (one of -// symlink or unlink), the file name of the symlink and the destination of the -// symlink. -func (c *Conn) DisableUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]DisableUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.DisableUnitFiles", 0, files, runtime).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]DisableUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -type DisableUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use MaskUnitFilesContext instead. -func (c *Conn) MaskUnitFiles(files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) { - return c.MaskUnitFilesContext(context.Background(), files, runtime, force) -} - -// MaskUnitFilesContext masks one or more units in the system. -// -// The files argument contains a list of units to mask (either just file names -// or full absolute paths if the unit files are residing outside the usual unit -// search paths). -// -// The runtime argument is used to specify whether the unit was enabled for -// runtime only (true, /run/systemd/..), or persistently (false, -// /etc/systemd/..). -func (c *Conn) MaskUnitFilesContext(ctx context.Context, files []string, runtime bool, force bool) ([]MaskUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.MaskUnitFiles", 0, files, runtime, force).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]MaskUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -type MaskUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use UnmaskUnitFilesContext instead. -func (c *Conn) UnmaskUnitFiles(files []string, runtime bool) ([]UnmaskUnitFileChange, error) { - return c.UnmaskUnitFilesContext(context.Background(), files, runtime) -} - -// UnmaskUnitFilesContext unmasks one or more units in the system. -// -// It takes the list of unit files to mask (either just file names or full -// absolute paths if the unit files are residing outside the usual unit search -// paths), and a boolean runtime flag to specify whether the unit was enabled -// for runtime only (true, /run/systemd/..), or persistently (false, -// /etc/systemd/..). -func (c *Conn) UnmaskUnitFilesContext(ctx context.Context, files []string, runtime bool) ([]UnmaskUnitFileChange, error) { - result := make([][]interface{}, 0) - err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.UnmaskUnitFiles", 0, files, runtime).Store(&result) - if err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - changes := make([]UnmaskUnitFileChange, len(result)) - changesInterface := make([]interface{}, len(changes)) - for i := range changes { - changesInterface[i] = &changes[i] - } - - err = dbus.Store(resultInterface, changesInterface...) - if err != nil { - return nil, err - } - - return changes, nil -} - -type UnmaskUnitFileChange struct { - Type string // Type of the change (one of symlink or unlink) - Filename string // File name of the symlink - Destination string // Destination of the symlink -} - -// Deprecated: use ReloadContext instead. -func (c *Conn) Reload() error { - return c.ReloadContext(context.Background()) -} - -// ReloadContext instructs systemd to scan for and reload unit files. This is -// an equivalent to systemctl daemon-reload. -func (c *Conn) ReloadContext(ctx context.Context) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.Reload", 0).Store() -} - -func unitPath(name string) dbus.ObjectPath { - return dbus.ObjectPath("/org/freedesktop/systemd1/unit/" + PathBusEscape(name)) -} - -// unitName returns the unescaped base element of the supplied escaped path. -func unitName(dpath dbus.ObjectPath) string { - return pathBusUnescape(path.Base(string(dpath))) -} - -// JobStatus holds a currently queued job definition. -type JobStatus struct { - Id uint32 // The numeric job id - Unit string // The primary unit name for this job - JobType string // The job type as string - Status string // The job state as string - JobPath dbus.ObjectPath // The job object path - UnitPath dbus.ObjectPath // The unit object path -} - -// Deprecated: use ListJobsContext instead. -func (c *Conn) ListJobs() ([]JobStatus, error) { - return c.ListJobsContext(context.Background()) -} - -// ListJobsContext returns an array with all currently queued jobs. -func (c *Conn) ListJobsContext(ctx context.Context) ([]JobStatus, error) { - return c.listJobsInternal(ctx) -} - -func (c *Conn) listJobsInternal(ctx context.Context) ([]JobStatus, error) { - result := make([][]interface{}, 0) - if err := c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ListJobs", 0).Store(&result); err != nil { - return nil, err - } - - resultInterface := make([]interface{}, len(result)) - for i := range result { - resultInterface[i] = result[i] - } - - status := make([]JobStatus, len(result)) - statusInterface := make([]interface{}, len(status)) - for i := range status { - statusInterface[i] = &status[i] - } - - if err := dbus.Store(resultInterface, statusInterface...); err != nil { - return nil, err - } - - return status, nil -} - -// Freeze the cgroup associated with the unit. -// Note that FreezeUnit and ThawUnit are only supported on systems running with cgroup v2. -func (c *Conn) FreezeUnit(ctx context.Context, unit string) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.FreezeUnit", 0, unit).Store() -} - -// Unfreeze the cgroup associated with the unit. -func (c *Conn) ThawUnit(ctx context.Context, unit string) error { - return c.sysobj.CallWithContext(ctx, "org.freedesktop.systemd1.Manager.ThawUnit", 0, unit).Store() -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go b/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go deleted file mode 100644 index fb42b6273..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/properties.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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 dbus - -import ( - "github.com/godbus/dbus/v5" -) - -// From the systemd docs: -// -// The properties array of StartTransientUnit() may take many of the settings -// that may also be configured in unit files. Not all parameters are currently -// accepted though, but we plan to cover more properties with future release. -// Currently you may set the Description, Slice and all dependency types of -// units, as well as RemainAfterExit, ExecStart for service units, -// TimeoutStopUSec and PIDs for scope units, and CPUAccounting, CPUShares, -// BlockIOAccounting, BlockIOWeight, BlockIOReadBandwidth, -// BlockIOWriteBandwidth, BlockIODeviceWeight, MemoryAccounting, MemoryLimit, -// DevicePolicy, DeviceAllow for services/scopes/slices. These fields map -// directly to their counterparts in unit files and as normal D-Bus object -// properties. The exception here is the PIDs field of scope units which is -// used for construction of the scope only and specifies the initial PIDs to -// add to the scope object. - -type Property struct { - Name string - Value dbus.Variant -} - -type PropertyCollection struct { - Name string - Properties []Property -} - -type execStart struct { - Path string // the binary path to execute - Args []string // an array with all arguments to pass to the executed command, starting with argument 0 - UncleanIsFailure bool // a boolean whether it should be considered a failure if the process exits uncleanly -} - -// PropExecStart sets the ExecStart service property. The first argument is a -// slice with the binary path to execute followed by the arguments to pass to -// the executed command. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart= -func PropExecStart(command []string, uncleanIsFailure bool) Property { - execStarts := []execStart{ - { - Path: command[0], - Args: command, - UncleanIsFailure: uncleanIsFailure, - }, - } - - return Property{ - Name: "ExecStart", - Value: dbus.MakeVariant(execStarts), - } -} - -// PropRemainAfterExit sets the RemainAfterExit service property. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#RemainAfterExit= -func PropRemainAfterExit(b bool) Property { - return Property{ - Name: "RemainAfterExit", - Value: dbus.MakeVariant(b), - } -} - -// PropType sets the Type service property. See -// http://www.freedesktop.org/software/systemd/man/systemd.service.html#Type= -func PropType(t string) Property { - return Property{ - Name: "Type", - Value: dbus.MakeVariant(t), - } -} - -// PropDescription sets the Description unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit#Description= -func PropDescription(desc string) Property { - return Property{ - Name: "Description", - Value: dbus.MakeVariant(desc), - } -} - -func propDependency(name string, units []string) Property { - return Property{ - Name: name, - Value: dbus.MakeVariant(units), - } -} - -// PropRequires sets the Requires unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requires= -func PropRequires(units ...string) Property { - return propDependency("Requires", units) -} - -// PropRequiresOverridable sets the RequiresOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresOverridable= -func PropRequiresOverridable(units ...string) Property { - return propDependency("RequiresOverridable", units) -} - -// PropRequisite sets the Requisite unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Requisite= -func PropRequisite(units ...string) Property { - return propDependency("Requisite", units) -} - -// PropRequisiteOverridable sets the RequisiteOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequisiteOverridable= -func PropRequisiteOverridable(units ...string) Property { - return propDependency("RequisiteOverridable", units) -} - -// PropWants sets the Wants unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Wants= -func PropWants(units ...string) Property { - return propDependency("Wants", units) -} - -// PropBindsTo sets the BindsTo unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#BindsTo= -func PropBindsTo(units ...string) Property { - return propDependency("BindsTo", units) -} - -// PropRequiredBy sets the RequiredBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredBy= -func PropRequiredBy(units ...string) Property { - return propDependency("RequiredBy", units) -} - -// PropRequiredByOverridable sets the RequiredByOverridable unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiredByOverridable= -func PropRequiredByOverridable(units ...string) Property { - return propDependency("RequiredByOverridable", units) -} - -// PropWantedBy sets the WantedBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#WantedBy= -func PropWantedBy(units ...string) Property { - return propDependency("WantedBy", units) -} - -// PropBoundBy sets the BoundBy unit property. See -// http://www.freedesktop.org/software/systemd/main/systemd.unit.html#BoundBy= -func PropBoundBy(units ...string) Property { - return propDependency("BoundBy", units) -} - -// PropConflicts sets the Conflicts unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Conflicts= -func PropConflicts(units ...string) Property { - return propDependency("Conflicts", units) -} - -// PropConflictedBy sets the ConflictedBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#ConflictedBy= -func PropConflictedBy(units ...string) Property { - return propDependency("ConflictedBy", units) -} - -// PropBefore sets the Before unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Before= -func PropBefore(units ...string) Property { - return propDependency("Before", units) -} - -// PropAfter sets the After unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#After= -func PropAfter(units ...string) Property { - return propDependency("After", units) -} - -// PropOnFailure sets the OnFailure unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#OnFailure= -func PropOnFailure(units ...string) Property { - return propDependency("OnFailure", units) -} - -// PropTriggers sets the Triggers unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#Triggers= -func PropTriggers(units ...string) Property { - return propDependency("Triggers", units) -} - -// PropTriggeredBy sets the TriggeredBy unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#TriggeredBy= -func PropTriggeredBy(units ...string) Property { - return propDependency("TriggeredBy", units) -} - -// PropPropagatesReloadTo sets the PropagatesReloadTo unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#PropagatesReloadTo= -func PropPropagatesReloadTo(units ...string) Property { - return propDependency("PropagatesReloadTo", units) -} - -// PropRequiresMountsFor sets the RequiresMountsFor unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.unit.html#RequiresMountsFor= -func PropRequiresMountsFor(units ...string) Property { - return propDependency("RequiresMountsFor", units) -} - -// PropSlice sets the Slice unit property. See -// http://www.freedesktop.org/software/systemd/man/systemd.resource-control.html#Slice= -func PropSlice(slice string) Property { - return Property{ - Name: "Slice", - Value: dbus.MakeVariant(slice), - } -} - -// PropPids sets the PIDs field of scope units used in the initial construction -// of the scope only and specifies the initial PIDs to add to the scope object. -// See https://www.freedesktop.org/wiki/Software/systemd/ControlGroupInterface/#properties -func PropPids(pids ...uint32) Property { - return Property{ - Name: "PIDs", - Value: dbus.MakeVariant(pids), - } -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/set.go deleted file mode 100644 index 17c5d4856..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/set.go +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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 dbus - -type set struct { - data map[string]bool -} - -func (s *set) Add(value string) { - s.data[value] = true -} - -func (s *set) Remove(value string) { - delete(s.data, value) -} - -func (s *set) Contains(value string) (exists bool) { - _, exists = s.data[value] - return -} - -func (s *set) Length() int { - return len(s.data) -} - -func (s *set) Values() (values []string) { - for val := range s.data { - values = append(values, val) - } - return -} - -func newSet() *set { - return &set{make(map[string]bool)} -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go deleted file mode 100644 index 7e370fea2..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription.go +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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 dbus - -import ( - "errors" - "log" - "time" - - "github.com/godbus/dbus/v5" -) - -const ( - cleanIgnoreInterval = int64(10 * time.Second) - ignoreInterval = int64(30 * time.Millisecond) -) - -// Subscribe sets up this connection to subscribe to all systemd dbus events. -// This is required before calling SubscribeUnits. When the connection closes -// systemd will automatically stop sending signals so there is no need to -// explicitly call Unsubscribe(). -func (c *Conn) Subscribe() error { - c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal',interface='org.freedesktop.systemd1.Manager',member='UnitNew'") - c.sigconn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, - "type='signal',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'") - - return c.sigobj.Call("org.freedesktop.systemd1.Manager.Subscribe", 0).Store() -} - -// Unsubscribe this connection from systemd dbus events. -func (c *Conn) Unsubscribe() error { - return c.sigobj.Call("org.freedesktop.systemd1.Manager.Unsubscribe", 0).Store() -} - -func (c *Conn) dispatch() { - ch := make(chan *dbus.Signal, signalBuffer) - - c.sigconn.Signal(ch) - - go func() { - for { - signal, ok := <-ch - if !ok { - return - } - - if signal.Name == "org.freedesktop.systemd1.Manager.JobRemoved" { - c.jobComplete(signal) - } - - if c.subStateSubscriber.updateCh == nil && - c.propertiesSubscriber.updateCh == nil { - continue - } - - var unitPath dbus.ObjectPath - switch signal.Name { - case "org.freedesktop.systemd1.Manager.JobRemoved": - unitName := signal.Body[2].(string) - c.sysobj.Call("org.freedesktop.systemd1.Manager.GetUnit", 0, unitName).Store(&unitPath) - case "org.freedesktop.systemd1.Manager.UnitNew": - unitPath = signal.Body[1].(dbus.ObjectPath) - case "org.freedesktop.DBus.Properties.PropertiesChanged": - if signal.Body[0].(string) == "org.freedesktop.systemd1.Unit" { - unitPath = signal.Path - - if len(signal.Body) >= 2 { - if changed, ok := signal.Body[1].(map[string]dbus.Variant); ok { - c.sendPropertiesUpdate(unitPath, changed) - } - } - } - } - - if unitPath == dbus.ObjectPath("") { - continue - } - - c.sendSubStateUpdate(unitPath) - } - }() -} - -// SubscribeUnits returns two unbuffered channels which will receive all changed units every -// interval. Deleted units are sent as nil. -func (c *Conn) SubscribeUnits(interval time.Duration) (<-chan map[string]*UnitStatus, <-chan error) { - return c.SubscribeUnitsCustom(interval, 0, func(u1, u2 *UnitStatus) bool { return *u1 != *u2 }, nil) -} - -// SubscribeUnitsCustom is like SubscribeUnits but lets you specify the buffer -// size of the channels, the comparison function for detecting changes and a filter -// function for cutting down on the noise that your channel receives. -func (c *Conn) SubscribeUnitsCustom(interval time.Duration, buffer int, isChanged func(*UnitStatus, *UnitStatus) bool, filterUnit func(string) bool) (<-chan map[string]*UnitStatus, <-chan error) { - old := make(map[string]*UnitStatus) - statusChan := make(chan map[string]*UnitStatus, buffer) - errChan := make(chan error, buffer) - - go func() { - for { - timerChan := time.After(interval) - - units, err := c.ListUnits() - if err == nil { - cur := make(map[string]*UnitStatus) - for i := range units { - if filterUnit != nil && filterUnit(units[i].Name) { - continue - } - cur[units[i].Name] = &units[i] - } - - // add all new or changed units - changed := make(map[string]*UnitStatus) - for n, u := range cur { - if oldU, ok := old[n]; !ok || isChanged(oldU, u) { - changed[n] = u - } - delete(old, n) - } - - // add all deleted units - for oldN := range old { - changed[oldN] = nil - } - - old = cur - - if len(changed) != 0 { - statusChan <- changed - } - } else { - errChan <- err - } - - <-timerChan - } - }() - - return statusChan, errChan -} - -type SubStateUpdate struct { - UnitName string - SubState string -} - -// SetSubStateSubscriber writes to updateCh when any unit's substate changes. -// Although this writes to updateCh on every state change, the reported state -// may be more recent than the change that generated it (due to an unavoidable -// race in the systemd dbus interface). That is, this method provides a good -// way to keep a current view of all units' states, but is not guaranteed to -// show every state transition they go through. Furthermore, state changes -// will only be written to the channel with non-blocking writes. If updateCh -// is full, it attempts to write an error to errCh; if errCh is full, the error -// passes silently. -func (c *Conn) SetSubStateSubscriber(updateCh chan<- *SubStateUpdate, errCh chan<- error) { - if c == nil { - msg := "nil receiver" - select { - case errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } - - c.subStateSubscriber.Lock() - defer c.subStateSubscriber.Unlock() - c.subStateSubscriber.updateCh = updateCh - c.subStateSubscriber.errCh = errCh -} - -func (c *Conn) sendSubStateUpdate(unitPath dbus.ObjectPath) { - c.subStateSubscriber.Lock() - defer c.subStateSubscriber.Unlock() - - if c.subStateSubscriber.updateCh == nil { - return - } - - isIgnored := c.shouldIgnore(unitPath) - defer c.cleanIgnore() - if isIgnored { - return - } - - info, err := c.GetUnitPathProperties(unitPath) - if err != nil { - select { - case c.subStateSubscriber.errCh <- err: - default: - log.Printf("full error channel while reporting: %s\n", err) - } - return - } - defer c.updateIgnore(unitPath, info) - - name, ok := info["Id"].(string) - if !ok { - msg := "failed to cast info.Id" - select { - case c.subStateSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", err) - } - return - } - substate, ok := info["SubState"].(string) - if !ok { - msg := "failed to cast info.SubState" - select { - case c.subStateSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } - - update := &SubStateUpdate{name, substate} - select { - case c.subStateSubscriber.updateCh <- update: - default: - msg := "update channel is full" - select { - case c.subStateSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } -} - -// The ignore functions work around a wart in the systemd dbus interface. -// Requesting the properties of an unloaded unit will cause systemd to send a -// pair of UnitNew/UnitRemoved signals. Because we need to get a unit's -// properties on UnitNew (as that's the only indication of a new unit coming up -// for the first time), we would enter an infinite loop if we did not attempt -// to detect and ignore these spurious signals. The signal themselves are -// indistinguishable from relevant ones, so we (somewhat hackishly) ignore an -// unloaded unit's signals for a short time after requesting its properties. -// This means that we will miss e.g. a transient unit being restarted -// *immediately* upon failure and also a transient unit being started -// immediately after requesting its status (with systemctl status, for example, -// because this causes a UnitNew signal to be sent which then causes us to fetch -// the properties). - -func (c *Conn) shouldIgnore(path dbus.ObjectPath) bool { - t, ok := c.subStateSubscriber.ignore[path] - return ok && t >= time.Now().UnixNano() -} - -func (c *Conn) updateIgnore(path dbus.ObjectPath, info map[string]interface{}) { - loadState, ok := info["LoadState"].(string) - if !ok { - return - } - - // unit is unloaded - it will trigger bad systemd dbus behavior - if loadState == "not-found" { - c.subStateSubscriber.ignore[path] = time.Now().UnixNano() + ignoreInterval - } -} - -// without this, ignore would grow unboundedly over time -func (c *Conn) cleanIgnore() { - now := time.Now().UnixNano() - if c.subStateSubscriber.cleanIgnore < now { - c.subStateSubscriber.cleanIgnore = now + cleanIgnoreInterval - - for p, t := range c.subStateSubscriber.ignore { - if t < now { - delete(c.subStateSubscriber.ignore, p) - } - } - } -} - -// PropertiesUpdate holds a map of a unit's changed properties -type PropertiesUpdate struct { - UnitName string - Changed map[string]dbus.Variant -} - -// SetPropertiesSubscriber writes to updateCh when any unit's properties -// change. Every property change reported by systemd will be sent; that is, no -// transitions will be "missed" (as they might be with SetSubStateSubscriber). -// However, state changes will only be written to the channel with non-blocking -// writes. If updateCh is full, it attempts to write an error to errCh; if -// errCh is full, the error passes silently. -func (c *Conn) SetPropertiesSubscriber(updateCh chan<- *PropertiesUpdate, errCh chan<- error) { - c.propertiesSubscriber.Lock() - defer c.propertiesSubscriber.Unlock() - c.propertiesSubscriber.updateCh = updateCh - c.propertiesSubscriber.errCh = errCh -} - -// we don't need to worry about shouldIgnore() here because -// sendPropertiesUpdate doesn't call GetProperties() -func (c *Conn) sendPropertiesUpdate(unitPath dbus.ObjectPath, changedProps map[string]dbus.Variant) { - c.propertiesSubscriber.Lock() - defer c.propertiesSubscriber.Unlock() - - if c.propertiesSubscriber.updateCh == nil { - return - } - - update := &PropertiesUpdate{unitName(unitPath), changedProps} - - select { - case c.propertiesSubscriber.updateCh <- update: - default: - msg := "update channel is full" - select { - case c.propertiesSubscriber.errCh <- errors.New(msg): - default: - log.Printf("full error channel while reporting: %s\n", msg) - } - return - } -} diff --git a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go b/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go deleted file mode 100644 index 5b408d584..000000000 --- a/vendor/github.com/coreos/go-systemd/v22/dbus/subscription_set.go +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015 CoreOS, Inc. -// -// 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 dbus - -import ( - "time" -) - -// SubscriptionSet returns a subscription set which is like conn.Subscribe but -// can filter to only return events for a set of units. -type SubscriptionSet struct { - *set - conn *Conn -} - -func (s *SubscriptionSet) filter(unit string) bool { - return !s.Contains(unit) -} - -// Subscribe starts listening for dbus events for all of the units in the set. -// Returns channels identical to conn.SubscribeUnits. -func (s *SubscriptionSet) Subscribe() (<-chan map[string]*UnitStatus, <-chan error) { - // TODO: Make fully evented by using systemd 209 with properties changed values - return s.conn.SubscribeUnitsCustom(time.Second, 0, - mismatchUnitStatus, - func(unit string) bool { return s.filter(unit) }, - ) -} - -// NewSubscriptionSet returns a new subscription set. -func (conn *Conn) NewSubscriptionSet() *SubscriptionSet { - return &SubscriptionSet{newSet(), conn} -} - -// mismatchUnitStatus returns true if the provided UnitStatus objects -// are not equivalent. false is returned if the objects are equivalent. -// Only the Name, Description and state-related fields are used in -// the comparison. -func mismatchUnitStatus(u1, u2 *UnitStatus) bool { - return u1.Name != u2.Name || - u1.Description != u2.Description || - u1.LoadState != u2.LoadState || - u1.ActiveState != u2.ActiveState || - u1.SubState != u2.SubState -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml b/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml deleted file mode 100644 index 3e8dd99bd..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/.golangci.yml +++ /dev/null @@ -1,60 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 - -# Copyright (C) 2025 Aleksa Sarai -# Copyright (C) 2025 SUSE LLC -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -version: "2" - -run: - build-tags: - - libpathrs - -linters: - enable: - - asasalint - - asciicheck - - containedctx - - contextcheck - - errcheck - - errorlint - - exhaustive - - forcetypeassert - - godot - - goprintffuncname - - govet - - importas - - ineffassign - - makezero - - misspell - - musttag - - nilerr - - nilnesserr - - nilnil - - noctx - - prealloc - - revive - - staticcheck - - testifylint - - unconvert - - unparam - - unused - - usetesting - settings: - govet: - enable: - - nilness - testifylint: - enable-all: true - -formatters: - enable: - - gofumpt - - goimports - settings: - goimports: - local-prefixes: - - github.com/cyphar/filepath-securejoin diff --git a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md b/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md deleted file mode 100644 index 734cf61e3..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/CHANGELOG.md +++ /dev/null @@ -1,461 +0,0 @@ -# Changelog # -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/) -and this project adheres to [Semantic Versioning](http://semver.org/). - -## [Unreleased] ## - -## [0.6.0] - 2025-11-03 ## - -> By the Power of Greyskull! - -While quite small code-wise, this release marks a very key point in the -development of filepath-securejoin. - -filepath-securejoin was originally intended (back in 2017) to simply be a -single-purpose library that would take some common code used in container -runtimes (specifically, Docker's `FollowSymlinksInScope`) and make it more -general-purpose (with the eventual goals of it ending up in the Go stdlib). - -Of course, I quickly discovered that this problem was actually far more -complicated to solve when dealing with racing attackers, which lead to me -developing `openat2(2)` and [libpathrs][]. I had originally planned for -libpathrs to completely replace filepath-securejoin "once it was ready" but in -the interim we needed to fix several race attacks in runc as part of security -advisories. Obviously we couldn't require the usage of a pre-0.1 Rust library -in runc so it was necessary to port bits of libpathrs into filepath-securejoin. -(Ironically the first prototypes of libpathrs were originally written in Go and -then rewritten to Rust, so the code in filepath-securejoin is actually Go code -that was rewritten to Rust then re-rewritten to Go.) - -It then became clear that pure-Go libraries will likely not be willing to -require CGo for all of their builds, so it was necessary to accept that -filepath-securejoin will need to stay. As such, in v0.5.0 we provided more -pure-Go implementations of features from libpathrs but moved them into -`pathrs-lite` subpackage to clarify what purpose these helpers serve. - -This release finally closes the loop and makes it so that pathrs-lite can -transparently use libpathrs (via a `libpathrs` build-tag). This means that -upstream libraries can use the pure Go version if they prefer, but downstreams -(either downstream library users or even downstream distributions) are able to -migrate to libpathrs for all usages of pathrs-lite in an entire Go binary. - -I should make it clear that I do not plan to port the rest of libpathrs to Go, -as I do not wish to maintain two copies of the same codebase. pathrs-lite -already provides the core essentials necessary to operate on paths safely for -most modern systems. Users who want additional hardening or more ergonomic APIs -are free to use [`cyphar.com/go-pathrs`][go-pathrs] (libpathrs's Go bindings). - -[libpathrs]: https://github.com/cyphar/libpathrs -[go-pathrs]: https://cyphar.com/go-pathrs - -### Breaking ### -- The deprecated `MkdirAll`, `MkdirAllHandle`, `OpenInRoot`, `OpenatInRoot` and - `Reopen` wrappers have been removed. Please switch to using `pathrs-lite` - directly. - -### Added ### -- `pathrs-lite` now has support for using [libpathrs][libpathrs] as a backend. - This is opt-in and can be enabled at build time with the `libpathrs` build - tag. The intention is to allow for downstream libraries and other projects to - make use of the pure-Go `github.com/cyphar/filepath-securejoin/pathrs-lite` - package and distributors can then opt-in to using `libpathrs` for the entire - binary if they wish. - -## [0.5.1] - 2025-10-31 ## - -> Spooky scary skeletons send shivers down your spine! - -### Changed ### -- `openat2` can return `-EAGAIN` if it detects a possible attack in certain - scenarios (namely if there was a rename or mount while walking a path with a - `..` component). While this is necessary to avoid a denial-of-service in the - kernel, it does require retry loops in userspace. - - In previous versions, `pathrs-lite` would retry `openat2` 32 times before - returning an error, but we've received user reports that this limit can be - hit on systems with very heavy load. In some synthetic benchmarks (testing - the worst-case of an attacker doing renames in a tight loop on every core of - a 16-core machine) we managed to get a ~3% failure rate in runc. We have - improved this situation in two ways: - - * We have now increased this limit to 128, which should be good enough for - most use-cases without becoming a denial-of-service vector (the number of - syscalls called by the `O_PATH` resolver in a typical case is within the - same ballpark). The same benchmarks show a failure rate of ~0.12% which - (while not zero) is probably sufficient for most users. - - * In addition, we now return a `unix.EAGAIN` error that is bubbled up and can - be detected by callers. This means that callers with stricter requirements - to avoid spurious errors can choose to do their own infinite `EAGAIN` retry - loop (though we would strongly recommend users use time-based deadlines in - such retry loops to avoid potentially unbounded denials-of-service). - -## [0.5.0] - 2025-09-26 ## - -> Let the past die. Kill it if you have to. - -> **NOTE**: With this release, some parts of -> `github.com/cyphar/filepath-securejoin` are now licensed under the Mozilla -> Public License (version 2). Please see [COPYING.md][] as well as the the -> license header in each file for more details. - -[COPYING.md]: ./COPYING.md - -### Breaking ### -- The new API introduced in the [0.3.0][] release has been moved to a new - subpackage called `pathrs-lite`. This was primarily done to better indicate - the split between the new and old APIs, as well as indicate to users the - purpose of this subpackage (it is a less complete version of [libpathrs][]). - - We have added some wrappers to the top-level package to ease the transition, - but those are deprecated and will be removed in the next minor release of - filepath-securejoin. Users should update their import paths. - - This new subpackage has also been relicensed under the Mozilla Public License - (version 2), please see [COPYING.md][] for more details. - -### Added ### -- Most of the key bits the safe `procfs` API have now been exported and are - available in `github.com/cyphar/filepath-securejoin/pathrs-lite/procfs`. At - the moment this primarily consists of a new `procfs.Handle` API: - - * `OpenProcRoot` returns a new handle to `/proc`, endeavouring to make it - safe if possible (`subset=pid` to protect against mistaken write attacks - and leaks, as well as using `fsopen(2)` to avoid racing mount attacks). - - `OpenUnsafeProcRoot` returns a handle without attempting to create one - with `subset=pid`, which makes it more dangerous to leak. Most users - should use `OpenProcRoot` (even if you need to use `ProcRoot` as the base - of an operation, as filepath-securejoin will internally open a handle when - necessary). - - * The `(*procfs.Handle).Open*` family of methods lets you get a safe - `O_PATH` handle to subpaths within `/proc` for certain subpaths. - - For `OpenThreadSelf`, the returned `ProcThreadSelfCloser` needs to be - called after you completely finish using the handle (this is necessary - because Go is multi-threaded and `ProcThreadSelf` references - `/proc/thread-self` which may disappear if we do not - `runtime.LockOSThread` -- `ProcThreadSelfCloser` is currently equivalent - to `runtime.UnlockOSThread`). - - Note that you cannot open any `procfs` symlinks (most notably magic-links) - using this API. At the moment, filepath-securejoin does not support this - feature (but [libpathrs][] does). - - * `ProcSelfFdReadlink` lets you get the in-kernel path representation of a - file descriptor (think `readlink("/proc/self/fd/...")`), except that we - verify that there aren't any tricky overmounts that could fool the - process. - - Please be aware that the returned string is simply a snapshot at that - particular moment, and an attacker could move the file being pointed to. - In addition, complex namespace configurations could result in non-sensical - or confusing paths to be returned. The value received from this function - should only be used as secondary verification of some security property, - not as proof that a particular handle has a particular path. - - The procfs handle used internally by the API is the same as the rest of - `filepath-securejoin` (for privileged programs this is usually a private - in-process `procfs` instance created with `fsopen(2)`). - - As before, this is intended as a stop-gap before users migrate to - [libpathrs][], which provides a far more extensive safe `procfs` API and is - generally more robust. - -- Previously, the hardened procfs implementation (used internally within - `Reopen` and `Open(at)InRoot`) only protected against overmount attacks on - systems with `openat2(2)` (Linux 5.6) or systems with `fsopen(2)` or - `open_tree(2)` (Linux 5.2) and programs with privileges to use them (with - some caveats about locked mounts that probably affect very few users). For - other users, an attacker with the ability to create malicious mounts (on most - systems, a sysadmin) could trick you into operating on files you didn't - expect. This attack only really makes sense in the context of container - runtime implementations. - - This was considered a reasonable trade-off, as the long-term intention was to - get all users to just switch to [libpathrs][] if they wanted to use the safe - `procfs` API (which had more extensive protections, and is what these new - protections in `filepath-securejoin` are based on). However, as the API - is now being exported it seems unwise to advertise the API as "safe" if we do - not protect against known attacks. - - The procfs API is now more protected against attackers on systems lacking the - aforementioned protections. However, the most comprehensive of these - protections effectively rely on [`statx(STATX_MNT_ID)`][statx.2] (Linux 5.8). - On older kernel versions, there is no effective protection (there is some - minimal protection against non-`procfs` filesystem components but a - sufficiently clever attacker can work around those). In addition, - `STATX_MNT_ID` is vulnerable to mount ID reuse attacks by sufficiently - motivated and privileged attackers -- this problem is mitigated with - `STATX_MNT_ID_UNIQUE` (Linux 6.8) but that raises the minimum kernel version - for more protection. - - The fact that these protections are quite limited despite needing a fair bit - of extra code to handle was one of the primary reasons we did not initially - implement this in `filepath-securejoin` ([libpathrs][] supports all of this, - of course). - -### Fixed ### -- RHEL 8 kernels have backports of `fsopen(2)` but in some testing we've found - that it has very bad (and very difficult to debug) performance issues, and so - we will explicitly refuse to use `fsopen(2)` if the running kernel version is - pre-5.2 and will instead fallback to `open("/proc")`. - -[CVE-2024-21626]: https://github.com/opencontainers/runc/security/advisories/GHSA-xr7r-f8xq-vfvv -[libpathrs]: https://github.com/cyphar/libpathrs -[statx.2]: https://www.man7.org/linux/man-pages/man2/statx.2.html - -## [0.4.1] - 2025-01-28 ## - -### Fixed ### -- The restrictions added for `root` paths passed to `SecureJoin` in 0.4.0 was - found to be too strict and caused some regressions when folks tried to - update, so this restriction has been relaxed to only return an error if the - path contains a `..` component. We still recommend users use `filepath.Clean` - (and even `filepath.EvalSymlinks`) on the `root` path they are using, but at - least you will no longer be punished for "trivial" unclean paths. - -## [0.4.0] - 2025-01-13 ## - -### Breaking #### -- `SecureJoin(VFS)` will now return an error if the provided `root` is not a - `filepath.Clean`'d path. - - While it is ultimately the responsibility of the caller to ensure the root is - a safe path to use, passing a path like `/symlink/..` as a root would result - in the `SecureJoin`'d path being placed in `/` even though `/symlink/..` - might be a different directory, and so we should more strongly discourage - such usage. - - All major users of `securejoin.SecureJoin` already ensure that the paths they - provide are safe (and this is ultimately a question of user error), but - removing this foot-gun is probably a good idea. Of course, this is - necessarily a breaking API change (though we expect no real users to be - affected by it). - - Thanks to [Erik Sjölund](https://github.com/eriksjolund), who initially - reported this issue as a possible security issue. - -- `MkdirAll` and `MkdirHandle` now take an `os.FileMode`-style mode argument - instead of a raw `unix.S_*`-style mode argument, which may cause compile-time - type errors depending on how you use `filepath-securejoin`. For most users, - there will be no change in behaviour aside from the type change (as the - bottom `0o777` bits are the same in both formats, and most users are probably - only using those bits). - - However, if you were using `unix.S_ISVTX` to set the sticky bit with - `MkdirAll(Handle)` you will need to switch to `os.ModeSticky` otherwise you - will get a runtime error with this update. In addition, the error message you - will get from passing `unix.S_ISUID` and `unix.S_ISGID` will be different as - they are treated as invalid bits now (note that previously passing said bits - was also an error). - -## [0.3.6] - 2024-12-17 ## - -### Compatibility ### -- The minimum Go version requirement for `filepath-securejoin` is now Go 1.18 - (we use generics internally). - - For reference, `filepath-securejoin@v0.3.0` somewhat-arbitrarily bumped the - Go version requirement to 1.21. - - While we did make some use of Go 1.21 stdlib features (and in principle Go - versions <= 1.21 are no longer even supported by upstream anymore), some - downstreams have complained that the version bump has meant that they have to - do workarounds when backporting fixes that use the new `filepath-securejoin` - API onto old branches. This is not an ideal situation, but since using this - library is probably better for most downstreams than a hand-rolled - workaround, we now have compatibility shims that allow us to build on older - Go versions. -- Lower minimum version requirement for `golang.org/x/sys` to `v0.18.0` (we - need the wrappers for `fsconfig(2)`), which should also make backporting - patches to older branches easier. - -## [0.3.5] - 2024-12-06 ## - -### Fixed ### -- `MkdirAll` will now no longer return an `EEXIST` error if two racing - processes are creating the same directory. We will still verify that the path - is a directory, but this will avoid spurious errors when multiple threads or - programs are trying to `MkdirAll` the same path. opencontainers/runc#4543 - -## [0.3.4] - 2024-10-09 ## - -### Fixed ### -- Previously, some testing mocks we had resulted in us doing `import "testing"` - in non-`_test.go` code, which made some downstreams like Kubernetes unhappy. - This has been fixed. (#32) - -## [0.3.3] - 2024-09-30 ## - -### Fixed ### -- The mode and owner verification logic in `MkdirAll` has been removed. This - was originally intended to protect against some theoretical attacks but upon - further consideration these protections don't actually buy us anything and - they were causing spurious errors with more complicated filesystem setups. -- The "is the created directory empty" logic in `MkdirAll` has also been - removed. This was not causing us issues yet, but some pseudofilesystems (such - as `cgroup`) create non-empty directories and so this logic would've been - wrong for such cases. - -## [0.3.2] - 2024-09-13 ## - -### Changed ### -- Passing the `S_ISUID` or `S_ISGID` modes to `MkdirAllInRoot` will now return - an explicit error saying that those bits are ignored by `mkdirat(2)`. In the - past a different error was returned, but since the silent ignoring behaviour - is codified in the man pages a more explicit error seems apt. While silently - ignoring these bits would be the most compatible option, it could lead to - users thinking their code sets these bits when it doesn't. Programs that need - to deal with compatibility can mask the bits themselves. (#23, #25) - -### Fixed ### -- If a directory has `S_ISGID` set, then all child directories will have - `S_ISGID` set when created and a different gid will be used for any inode - created under the directory. Previously, the "expected owner and mode" - validation in `securejoin.MkdirAll` did not correctly handle this. We now - correctly handle this case. (#24, #25) - -## [0.3.1] - 2024-07-23 ## - -### Changed ### -- By allowing `Open(at)InRoot` to opt-out of the extra work done by `MkdirAll` - to do the necessary "partial lookups", `Open(at)InRoot` now does less work - for both implementations (resulting in a many-fold decrease in the number of - operations for `openat2`, and a modest improvement for non-`openat2`) and is - far more guaranteed to match the correct `openat2(RESOLVE_IN_ROOT)` - behaviour. -- We now use `readlinkat(fd, "")` where possible. For `Open(at)InRoot` this - effectively just means that we no longer risk getting spurious errors during - rename races. However, for our hardened procfs handler, this in theory should - prevent mount attacks from tricking us when doing magic-link readlinks (even - when using the unsafe host `/proc` handle). Unfortunately `Reopen` is still - potentially vulnerable to those kinds of somewhat-esoteric attacks. - - Technically this [will only work on post-2.6.39 kernels][linux-readlinkat-emptypath] - but it seems incredibly unlikely anyone is using `filepath-securejoin` on a - pre-2011 kernel. - -### Fixed ### -- Several improvements were made to the errors returned by `Open(at)InRoot` and - `MkdirAll` when dealing with invalid paths under the emulated (ie. - non-`openat2`) implementation. Previously, some paths would return the wrong - error (`ENOENT` when the last component was a non-directory), and other paths - would be returned as though they were acceptable (trailing-slash components - after a non-directory would be ignored by `Open(at)InRoot`). - - These changes were done to match `openat2`'s behaviour and purely is a - consistency fix (most users are going to be using `openat2` anyway). - -[linux-readlinkat-emptypath]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=65cfc6722361570bfe255698d9cd4dccaf47570d - -## [0.3.0] - 2024-07-11 ## - -### Added ### -- A new set of `*os.File`-based APIs have been added. These are adapted from - [libpathrs][] and we strongly suggest using them if possible (as they provide - far more protection against attacks than `SecureJoin`): - - - `Open(at)InRoot` resolves a path inside a rootfs and returns an `*os.File` - handle to the path. Note that the handle returned is an `O_PATH` handle, - which cannot be used for reading or writing (as well as some other - operations -- [see open(2) for more details][open.2]) - - - `Reopen` takes an `O_PATH` file handle and safely re-opens it to upgrade - it to a regular handle. This can also be used with non-`O_PATH` handles, - but `O_PATH` is the most obvious application. - - - `MkdirAll` is an implementation of `os.MkdirAll` that is safe to use to - create a directory tree within a rootfs. - - As these are new APIs, they may change in the future. However, they should be - safe to start migrating to as we have extensive tests ensuring they behave - correctly and are safe against various races and other attacks. - -[libpathrs]: https://github.com/cyphar/libpathrs -[open.2]: https://www.man7.org/linux/man-pages/man2/open.2.html - -## [0.2.5] - 2024-05-03 ## - -### Changed ### -- Some minor changes were made to how lexical components (like `..` and `.`) - are handled during path generation in `SecureJoin`. There is no behaviour - change as a result of this fix (the resulting paths are the same). - -### Fixed ### -- The error returned when we hit a symlink loop now references the correct - path. (#10) - -## [0.2.4] - 2023-09-06 ## - -### Security ### -- This release fixes a potential security issue in filepath-securejoin when - used on Windows ([GHSA-6xv5-86q9-7xr8][], which could be used to generate - paths outside of the provided rootfs in certain cases), as well as improving - the overall behaviour of filepath-securejoin when dealing with Windows paths - that contain volume names. Thanks to Paulo Gomes for discovering and fixing - these issues. - -### Fixed ### -- Switch to GitHub Actions for CI so we can test on Windows as well as Linux - and MacOS. - -[GHSA-6xv5-86q9-7xr8]: https://github.com/advisories/GHSA-6xv5-86q9-7xr8 - -## [0.2.3] - 2021-06-04 ## - -### Changed ### -- Switch to Go 1.13-style `%w` error wrapping, letting us drop the dependency - on `github.com/pkg/errors`. - -## [0.2.2] - 2018-09-05 ## - -### Changed ### -- Use `syscall.ELOOP` as the base error for symlink loops, rather than our own - (internal) error. This allows callers to more easily use `errors.Is` to check - for this case. - -## [0.2.1] - 2018-09-05 ## - -### Fixed ### -- Use our own `IsNotExist` implementation, which lets us handle `ENOTDIR` - properly within `SecureJoin`. - -## [0.2.0] - 2017-07-19 ## - -We now have 100% test coverage! - -### Added ### -- Add a `SecureJoinVFS` API that can be used for mocking (as we do in our new - tests) or for implementing custom handling of lookup operations (such as for - rootless containers, where work is necessary to access directories with weird - modes because we don't have `CAP_DAC_READ_SEARCH` or `CAP_DAC_OVERRIDE`). - -## 0.1.0 - 2017-07-19 - -This is our first release of `github.com/cyphar/filepath-securejoin`, -containing a full implementation with a coverage of 93.5% (the only missing -cases are the error cases, which are hard to mocktest at the moment). - -[Unreleased]: https://github.com/cyphar/filepath-securejoin/compare/v0.6.0...HEAD -[0.6.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.1...v0.6.0 -[0.5.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.5.0...v0.5.1 -[0.5.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.1...v0.5.0 -[0.4.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.4.0...v0.4.1 -[0.4.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.6...v0.4.0 -[0.3.6]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.5...v0.3.6 -[0.3.5]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.4...v0.3.5 -[0.3.4]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.3...v0.3.4 -[0.3.3]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.2...v0.3.3 -[0.3.2]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.1...v0.3.2 -[0.3.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.3.0...v0.3.1 -[0.3.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.5...v0.3.0 -[0.2.5]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.4...v0.2.5 -[0.2.4]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.3...v0.2.4 -[0.2.3]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.2...v0.2.3 -[0.2.2]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.1...v0.2.2 -[0.2.1]: https://github.com/cyphar/filepath-securejoin/compare/v0.2.0...v0.2.1 -[0.2.0]: https://github.com/cyphar/filepath-securejoin/compare/v0.1.0...v0.2.0 diff --git a/vendor/github.com/cyphar/filepath-securejoin/README.md b/vendor/github.com/cyphar/filepath-securejoin/README.md deleted file mode 100644 index 6673abfc8..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/README.md +++ /dev/null @@ -1,184 +0,0 @@ -## `filepath-securejoin` ## - -[![Go Documentation](https://pkg.go.dev/badge/github.com/cyphar/filepath-securejoin.svg)](https://pkg.go.dev/github.com/cyphar/filepath-securejoin) -[![Build Status](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml/badge.svg)](https://github.com/cyphar/filepath-securejoin/actions/workflows/ci.yml) - -### Old API ### - -This library was originally just an implementation of `SecureJoin` which was -[intended to be included in the Go standard library][go#20126] as a safer -`filepath.Join` that would restrict the path lookup to be inside a root -directory. - -The implementation was based on code that existed in several container -runtimes. Unfortunately, this API is **fundamentally unsafe** against attackers -that can modify path components after `SecureJoin` returns and before the -caller uses the path, allowing for some fairly trivial TOCTOU attacks. - -`SecureJoin` (and `SecureJoinVFS`) are still provided by this library to -support legacy users, but new users are strongly suggested to avoid using -`SecureJoin` and instead use the [new api](#new-api) or switch to -[libpathrs][libpathrs]. - -With the above limitations in mind, this library guarantees the following: - -* If no error is set, the resulting string **must** be a child path of - `root` and will not contain any symlink path components (they will all be - expanded). - -* When expanding symlinks, all symlink path components **must** be resolved - relative to the provided root. In particular, this can be considered a - userspace implementation of how `chroot(2)` operates on file paths. Note that - these symlinks will **not** be expanded lexically (`filepath.Clean` is not - called on the input before processing). - -* Non-existent path components are unaffected by `SecureJoin` (similar to - `filepath.EvalSymlinks`'s semantics). - -* The returned path will always be `filepath.Clean`ed and thus not contain any - `..` components. - -A (trivial) implementation of this function on GNU/Linux systems could be done -with the following (note that this requires root privileges and is far more -opaque than the implementation in this library, and also requires that -`readlink` is inside the `root` path and is trustworthy): - -```go -package securejoin - -import ( - "os/exec" - "path/filepath" -) - -func SecureJoin(root, unsafePath string) (string, error) { - unsafePath = string(filepath.Separator) + unsafePath - cmd := exec.Command("chroot", root, - "readlink", "--canonicalize-missing", "--no-newline", unsafePath) - output, err := cmd.CombinedOutput() - if err != nil { - return "", err - } - expanded := string(output) - return filepath.Join(root, expanded), nil -} -``` - -[libpathrs]: https://github.com/openSUSE/libpathrs -[go#20126]: https://github.com/golang/go/issues/20126 - -### New API ### -[#new-api]: #new-api - -While we recommend users switch to [libpathrs][libpathrs] as soon as it has a -stable release, some methods implemented by libpathrs have been ported to this -library to ease the transition. These APIs are only supported on Linux. - -These APIs are implemented such that `filepath-securejoin` will -opportunistically use certain newer kernel APIs that make these operations far -more secure. In particular: - -* All of the lookup operations will use [`openat2`][openat2.2] on new enough - kernels (Linux 5.6 or later) to restrict lookups through magic-links and - bind-mounts (for certain operations) and to make use of `RESOLVE_IN_ROOT` to - efficiently resolve symlinks within a rootfs. - -* The APIs provide hardening against a malicious `/proc` mount to either detect - or avoid being tricked by a `/proc` that is not legitimate. This is done - using [`openat2`][openat2.2] for all users, and privileged users will also be - further protected by using [`fsopen`][fsopen.2] and [`open_tree`][open_tree.2] - (Linux 5.2 or later). - -[openat2.2]: https://www.man7.org/linux/man-pages/man2/openat2.2.html -[fsopen.2]: https://github.com/brauner/man-pages-md/blob/main/fsopen.md -[open_tree.2]: https://github.com/brauner/man-pages-md/blob/main/open_tree.md - -#### `OpenInRoot` #### - -```go -func OpenInRoot(root, unsafePath string) (*os.File, error) -func OpenatInRoot(root *os.File, unsafePath string) (*os.File, error) -func Reopen(handle *os.File, flags int) (*os.File, error) -``` - -`OpenInRoot` is a much safer version of - -```go -path, err := securejoin.SecureJoin(root, unsafePath) -file, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC) -``` - -that protects against various race attacks that could lead to serious security -issues, depending on the application. Note that the returned `*os.File` is an -`O_PATH` file descriptor, which is quite restricted. Callers will probably need -to use `Reopen` to get a more usable handle (this split is done to provide -useful features like PTY spawning and to avoid users accidentally opening bad -inodes that could cause a DoS). - -Callers need to be careful in how they use the returned `*os.File`. Usually it -is only safe to operate on the handle directly, and it is very easy to create a -security issue. [libpathrs][libpathrs] provides far more helpers to make using -these handles safer -- there is currently no plan to port them to -`filepath-securejoin`. - -`OpenatInRoot` is like `OpenInRoot` except that the root is provided using an -`*os.File`. This allows you to ensure that multiple `OpenatInRoot` (or -`MkdirAllHandle`) calls are operating on the same rootfs. - -> **NOTE**: Unlike `SecureJoin`, `OpenInRoot` will error out as soon as it hits -> a dangling symlink or non-existent path. This is in contrast to `SecureJoin` -> which treated non-existent components as though they were real directories, -> and would allow for partial resolution of dangling symlinks. These behaviours -> are at odds with how Linux treats non-existent paths and dangling symlinks, -> and so these are no longer allowed. - -#### `MkdirAll` #### - -```go -func MkdirAll(root, unsafePath string, mode int) error -func MkdirAllHandle(root *os.File, unsafePath string, mode int) (*os.File, error) -``` - -`MkdirAll` is a much safer version of - -```go -path, err := securejoin.SecureJoin(root, unsafePath) -err = os.MkdirAll(path, mode) -``` - -that protects against the same kinds of races that `OpenInRoot` protects -against. - -`MkdirAllHandle` is like `MkdirAll` except that the root is provided using an -`*os.File` (the reason for this is the same as with `OpenatInRoot`) and an -`*os.File` of the final created directory is returned (this directory is -guaranteed to be effectively identical to the directory created by -`MkdirAllHandle`, which is not possible to ensure by just using `OpenatInRoot` -after `MkdirAll`). - -> **NOTE**: Unlike `SecureJoin`, `MkdirAll` will error out as soon as it hits -> a dangling symlink or non-existent path. This is in contrast to `SecureJoin` -> which treated non-existent components as though they were real directories, -> and would allow for partial resolution of dangling symlinks. These behaviours -> are at odds with how Linux treats non-existent paths and dangling symlinks, -> and so these are no longer allowed. This means that `MkdirAll` will not -> create non-existent directories referenced by a dangling symlink. - -### License ### - -`SPDX-License-Identifier: BSD-3-Clause AND MPL-2.0` - -Some of the code in this project is derived from Go, and is licensed under a -BSD 3-clause license (available in `LICENSE.BSD`). Other files (many of which -are derived from [libpathrs][libpathrs]) are licensed under the Mozilla Public -License version 2.0 (available in `LICENSE.MPL-2.0`). If you are using the -["New API" described above][#new-api], you are probably using code from files -released under this license. - -Every source file in this project has a copyright header describing its -license. Please check the license headers of each file to see what license -applies to it. - -See [COPYING.md](./COPYING.md) for some more details. - -[umoci]: https://github.com/opencontainers/umoci diff --git a/vendor/github.com/cyphar/filepath-securejoin/VERSION b/vendor/github.com/cyphar/filepath-securejoin/VERSION deleted file mode 100644 index a918a2aa1..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.6.0 diff --git a/vendor/github.com/cyphar/filepath-securejoin/codecov.yml b/vendor/github.com/cyphar/filepath-securejoin/codecov.yml deleted file mode 100644 index ff284dbfa..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/codecov.yml +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 - -# Copyright (C) 2025 Aleksa Sarai -# Copyright (C) 2025 SUSE LLC -# -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at https://mozilla.org/MPL/2.0/. - -comment: - layout: "condensed_header, reach, diff, components, condensed_files, condensed_footer" - require_changes: true - branches: - - main - -coverage: - range: 60..100 - status: - project: - default: - target: 85% - threshold: 0% - patch: - default: - target: auto - informational: true - -github_checks: - annotations: false diff --git a/vendor/github.com/cyphar/filepath-securejoin/doc.go b/vendor/github.com/cyphar/filepath-securejoin/doc.go deleted file mode 100644 index 1438fc9c0..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/doc.go +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. -// Copyright (C) 2017-2024 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package securejoin implements a set of helpers to make it easier to write Go -// code that is safe against symlink-related escape attacks. The primary idea -// is to let you resolve a path within a rootfs directory as if the rootfs was -// a chroot. -// -// securejoin has two APIs, a "legacy" API and a "modern" API. -// -// The legacy API is [SecureJoin] and [SecureJoinVFS]. These methods are -// **not** safe against race conditions where an attacker changes the -// filesystem after (or during) the [SecureJoin] operation. -// -// The new API is available in the [pathrs-lite] subpackage, and provide -// protections against racing attackers as well as several other key -// protections against attacks often seen by container runtimes. As the name -// suggests, [pathrs-lite] is a stripped down (pure Go) reimplementation of -// [libpathrs]. The main APIs provided are [OpenInRoot], [MkdirAll], and -// [procfs.Handle] -- other APIs are not planned to be ported. The long-term -// goal is for users to migrate to [libpathrs] which is more fully-featured. -// -// securejoin has been used by several container runtimes (Docker, runc, -// Kubernetes, etc) for quite a few years as a de-facto standard for operating -// on container filesystem paths "safely". However, most users still use the -// legacy API which is unsafe against various attacks (there is a fairly long -// history of CVEs in dependent as a result). Users should switch to the modern -// API as soon as possible (or even better, switch to libpathrs). -// -// This project was initially intended to be included in the Go standard -// library, but it was rejected (see https://go.dev/issue/20126). Much later, -// [os.Root] was added to the Go stdlib that shares some of the goals of -// filepath-securejoin. However, its design is intended to work like -// openat2(RESOLVE_BENEATH) which does not fit the usecase of container -// runtimes and most system tools. -// -// [pathrs-lite]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite -// [libpathrs]: https://github.com/openSUSE/libpathrs -// [OpenInRoot]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite#OpenInRoot -// [MkdirAll]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite#MkdirAll -// [procfs.Handle]: https://pkg.go.dev/github.com/cyphar/filepath-securejoin/pathrs-lite/procfs#Handle -// [os.Root]: https:///pkg.go.dev/os#Root -package securejoin diff --git a/vendor/github.com/cyphar/filepath-securejoin/join.go b/vendor/github.com/cyphar/filepath-securejoin/join.go deleted file mode 100644 index 199c1d839..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/join.go +++ /dev/null @@ -1,169 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -// Copyright (C) 2014-2015 Docker Inc & Go Authors. All rights reserved. -// Copyright (C) 2017-2025 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package securejoin - -import ( - "errors" - "os" - "path/filepath" - "strings" - "syscall" - - "github.com/cyphar/filepath-securejoin/internal/consts" -) - -// IsNotExist tells you if err is an error that implies that either the path -// accessed does not exist (or path components don't exist). This is -// effectively a more broad version of [os.IsNotExist]. -func IsNotExist(err error) bool { - // Check that it's not actually an ENOTDIR, which in some cases is a more - // convoluted case of ENOENT (usually involving weird paths). - return errors.Is(err, os.ErrNotExist) || errors.Is(err, syscall.ENOTDIR) || errors.Is(err, syscall.ENOENT) -} - -// errUnsafeRoot is returned if the user provides SecureJoinVFS with a path -// that contains ".." components. -var errUnsafeRoot = errors.New("root path provided to SecureJoin contains '..' components") - -// stripVolume just gets rid of the Windows volume included in a path. Based on -// some godbolt tests, the Go compiler is smart enough to make this a no-op on -// Linux. -func stripVolume(path string) string { - return path[len(filepath.VolumeName(path)):] -} - -// hasDotDot checks if the path contains ".." components in a platform-agnostic -// way. -func hasDotDot(path string) bool { - // If we are on Windows, strip any volume letters. It turns out that - // C:..\foo may (or may not) be a valid pathname and we need to handle that - // leading "..". - path = stripVolume(path) - // Look for "/../" in the path, but we need to handle leading and trailing - // ".."s by adding separators. Doing this with filepath.Separator is ugly - // so just convert to Unix-style "/" first. - path = filepath.ToSlash(path) - return strings.Contains("/"+path+"/", "/../") -} - -// SecureJoinVFS joins the two given path components (similar to -// [filepath.Join]) except that the returned path is guaranteed to be scoped -// inside the provided root path (when evaluated). Any symbolic links in the -// path are evaluated with the given root treated as the root of the -// filesystem, similar to a chroot. The filesystem state is evaluated through -// the given [VFS] interface (if nil, the standard [os].* family of functions -// are used). -// -// Note that the guarantees provided by this function only apply if the path -// components in the returned string are not modified (in other words are not -// replaced with symlinks on the filesystem) after this function has returned. -// Such a symlink race is necessarily out-of-scope of SecureJoinVFS. -// -// NOTE: Due to the above limitation, Linux users are strongly encouraged to -// use [OpenInRoot] instead, which does safely protect against these kinds of -// attacks. There is no way to solve this problem with SecureJoinVFS because -// the API is fundamentally wrong (you cannot return a "safe" path string and -// guarantee it won't be modified afterwards). -// -// Volume names in unsafePath are always discarded, regardless if they are -// provided via direct input or when evaluating symlinks. Therefore: -// -// "C:\Temp" + "D:\path\to\file.txt" results in "C:\Temp\path\to\file.txt" -// -// If the provided root is not [filepath.Clean] then an error will be returned, -// as such root paths are bordering on somewhat unsafe and using such paths is -// not best practice. We also strongly suggest that any root path is first -// fully resolved using [filepath.EvalSymlinks] or otherwise constructed to -// avoid containing symlink components. Of course, the root also *must not* be -// attacker-controlled. -func SecureJoinVFS(root, unsafePath string, vfs VFS) (string, error) { //nolint:revive // name is part of public API - // The root path must not contain ".." components, otherwise when we join - // the subpath we will end up with a weird path. We could work around this - // in other ways but users shouldn't be giving us non-lexical root paths in - // the first place. - if hasDotDot(root) { - return "", errUnsafeRoot - } - - // Use the os.* VFS implementation if none was specified. - if vfs == nil { - vfs = osVFS{} - } - - unsafePath = filepath.FromSlash(unsafePath) - var ( - currentPath string - remainingPath = unsafePath - linksWalked int - ) - for remainingPath != "" { - // On Windows, if we managed to end up at a path referencing a volume, - // drop the volume to make sure we don't end up with broken paths or - // escaping the root volume. - remainingPath = stripVolume(remainingPath) - - // Get the next path component. - var part string - if i := strings.IndexRune(remainingPath, filepath.Separator); i == -1 { - part, remainingPath = remainingPath, "" - } else { - part, remainingPath = remainingPath[:i], remainingPath[i+1:] - } - - // Apply the component lexically to the path we are building. - // currentPath does not contain any symlinks, and we are lexically - // dealing with a single component, so it's okay to do a filepath.Clean - // here. - nextPath := filepath.Join(string(filepath.Separator), currentPath, part) - if nextPath == string(filepath.Separator) { - currentPath = "" - continue - } - fullPath := root + string(filepath.Separator) + nextPath - - // Figure out whether the path is a symlink. - fi, err := vfs.Lstat(fullPath) - if err != nil && !IsNotExist(err) { - return "", err - } - // Treat non-existent path components the same as non-symlinks (we - // can't do any better here). - if IsNotExist(err) || fi.Mode()&os.ModeSymlink == 0 { - currentPath = nextPath - continue - } - - // It's a symlink, so get its contents and expand it by prepending it - // to the yet-unparsed path. - linksWalked++ - if linksWalked > consts.MaxSymlinkLimit { - return "", &os.PathError{Op: "SecureJoin", Path: root + string(filepath.Separator) + unsafePath, Err: syscall.ELOOP} - } - - dest, err := vfs.Readlink(fullPath) - if err != nil { - return "", err - } - remainingPath = dest + string(filepath.Separator) + remainingPath - // Absolute symlinks reset any work we've already done. - if filepath.IsAbs(dest) { - currentPath = "" - } - } - - // There should be no lexical components like ".." left in the path here, - // but for safety clean up the path before joining it to the root. - finalPath := filepath.Join(string(filepath.Separator), currentPath) - return filepath.Join(root, finalPath), nil -} - -// SecureJoin is a wrapper around [SecureJoinVFS] that just uses the [os].* library -// of functions as the [VFS]. If in doubt, use this function over [SecureJoinVFS]. -func SecureJoin(root, unsafePath string) (string, error) { - return SecureJoinVFS(root, unsafePath, nil) -} diff --git a/vendor/github.com/cyphar/filepath-securejoin/vfs.go b/vendor/github.com/cyphar/filepath-securejoin/vfs.go deleted file mode 100644 index 4d89a481c..000000000 --- a/vendor/github.com/cyphar/filepath-securejoin/vfs.go +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause - -// Copyright (C) 2017-2024 SUSE LLC. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package securejoin - -import "os" - -// In future this should be moved into a separate package, because now there -// are several projects (umoci and go-mtree) that are using this sort of -// interface. - -// VFS is the minimal interface necessary to use [SecureJoinVFS]. A nil VFS is -// equivalent to using the standard [os].* family of functions. This is mainly -// used for the purposes of mock testing, but also can be used to otherwise use -// [SecureJoinVFS] with VFS-like system. -type VFS interface { - // Lstat returns an [os.FileInfo] describing the named file. If the - // file is a symbolic link, the returned [os.FileInfo] describes the - // symbolic link. Lstat makes no attempt to follow the link. - // The semantics are identical to [os.Lstat]. - Lstat(name string) (os.FileInfo, error) - - // Readlink returns the destination of the named symbolic link. - // The semantics are identical to [os.Readlink]. - Readlink(name string) (string, error) -} - -// osVFS is the "nil" VFS, in that it just passes everything through to the os -// module. -type osVFS struct{} - -func (o osVFS) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) } - -func (o osVFS) Readlink(name string) (string, error) { return os.Readlink(name) } diff --git a/vendor/github.com/docker/go-units/CONTRIBUTING.md b/vendor/github.com/docker/go-units/CONTRIBUTING.md deleted file mode 100644 index 9ea86d784..000000000 --- a/vendor/github.com/docker/go-units/CONTRIBUTING.md +++ /dev/null @@ -1,67 +0,0 @@ -# Contributing to go-units - -Want to hack on go-units? Awesome! Here are instructions to get you started. - -go-units is a part of the [Docker](https://www.docker.com) project, and follows -the same rules and principles. If you're already familiar with the way -Docker does things, you'll feel right at home. - -Otherwise, go read Docker's -[contributions guidelines](https://github.com/docker/docker/blob/master/CONTRIBUTING.md), -[issue triaging](https://github.com/docker/docker/blob/master/project/ISSUE-TRIAGE.md), -[review process](https://github.com/docker/docker/blob/master/project/REVIEWING.md) and -[branches and tags](https://github.com/docker/docker/blob/master/project/BRANCHES-AND-TAGS.md). - -### Sign your work - -The sign-off is a simple line at the end of the explanation for the patch. Your -signature certifies that you wrote the patch or otherwise have the right to pass -it on as an open-source patch. The rules are pretty simple: if you can certify -the below (from [developercertificate.org](http://developercertificate.org/)): - -``` -Developer Certificate of Origin -Version 1.1 - -Copyright (C) 2004, 2006 The Linux Foundation and its contributors. -660 York Street, Suite 102, -San Francisco, CA 94110 USA - -Everyone is permitted to copy and distribute verbatim copies of this -license document, but changing it is not allowed. - -Developer's Certificate of Origin 1.1 - -By making a contribution to this project, I certify that: - -(a) The contribution was created in whole or in part by me and I - have the right to submit it under the open source license - indicated in the file; or - -(b) The contribution is based upon previous work that, to the best - of my knowledge, is covered under an appropriate open source - license and I have the right under that license to submit that - work with modifications, whether created in whole or in part - by me, under the same open source license (unless I am - permitted to submit under a different license), as indicated - in the file; or - -(c) The contribution was provided directly to me by some other - person who certified (a), (b) or (c) and I have not modified - it. - -(d) I understand and agree that this project and the contribution - are public and that a record of the contribution (including all - personal information I submit with it, including my sign-off) is - maintained indefinitely and may be redistributed consistent with - this project or the open source license(s) involved. -``` - -Then you just add a line to every git commit message: - - Signed-off-by: Joe Smith - -Use your real name (sorry, no pseudonyms or anonymous contributions.) - -If you set your `user.name` and `user.email` git configs, you can sign your -commit automatically with `git commit -s`. diff --git a/vendor/github.com/docker/go-units/LICENSE b/vendor/github.com/docker/go-units/LICENSE deleted file mode 100644 index b55b37bc3..000000000 --- a/vendor/github.com/docker/go-units/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2015 Docker, Inc. - - 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 - - https://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. diff --git a/vendor/github.com/docker/go-units/MAINTAINERS b/vendor/github.com/docker/go-units/MAINTAINERS deleted file mode 100644 index 4aac7c741..000000000 --- a/vendor/github.com/docker/go-units/MAINTAINERS +++ /dev/null @@ -1,46 +0,0 @@ -# go-units maintainers file -# -# This file describes who runs the docker/go-units project and how. -# This is a living document - if you see something out of date or missing, speak up! -# -# It is structured to be consumable by both humans and programs. -# To extract its contents programmatically, use any TOML-compliant parser. -# -# This file is compiled into the MAINTAINERS file in docker/opensource. -# -[Org] - [Org."Core maintainers"] - people = [ - "akihirosuda", - "dnephin", - "thajeztah", - "vdemeester", - ] - -[people] - -# A reference list of all people associated with the project. -# All other sections should refer to people by their canonical key -# in the people section. - - # ADD YOURSELF HERE IN ALPHABETICAL ORDER - - [people.akihirosuda] - Name = "Akihiro Suda" - Email = "akihiro.suda.cz@hco.ntt.co.jp" - GitHub = "AkihiroSuda" - - [people.dnephin] - Name = "Daniel Nephin" - Email = "dnephin@gmail.com" - GitHub = "dnephin" - - [people.thajeztah] - Name = "Sebastiaan van Stijn" - Email = "github@gone.nl" - GitHub = "thaJeztah" - - [people.vdemeester] - Name = "Vincent Demeester" - Email = "vincent@sbr.pm" - GitHub = "vdemeester" \ No newline at end of file diff --git a/vendor/github.com/docker/go-units/README.md b/vendor/github.com/docker/go-units/README.md deleted file mode 100644 index 4f70a4e13..000000000 --- a/vendor/github.com/docker/go-units/README.md +++ /dev/null @@ -1,16 +0,0 @@ -[![GoDoc](https://godoc.org/github.com/docker/go-units?status.svg)](https://godoc.org/github.com/docker/go-units) - -# Introduction - -go-units is a library to transform human friendly measurements into machine friendly values. - -## Usage - -See the [docs in godoc](https://godoc.org/github.com/docker/go-units) for examples and documentation. - -## Copyright and license - -Copyright © 2015 Docker, Inc. - -go-units is licensed under the Apache License, Version 2.0. -See [LICENSE](LICENSE) for the full text of the license. diff --git a/vendor/github.com/docker/go-units/circle.yml b/vendor/github.com/docker/go-units/circle.yml deleted file mode 100644 index af9d60552..000000000 --- a/vendor/github.com/docker/go-units/circle.yml +++ /dev/null @@ -1,11 +0,0 @@ -dependencies: - post: - # install golint - - go get golang.org/x/lint/golint - -test: - pre: - # run analysis before tests - - go vet ./... - - test -z "$(golint ./... | tee /dev/stderr)" - - test -z "$(gofmt -s -l . | tee /dev/stderr)" diff --git a/vendor/github.com/docker/go-units/duration.go b/vendor/github.com/docker/go-units/duration.go deleted file mode 100644 index 48dd8744d..000000000 --- a/vendor/github.com/docker/go-units/duration.go +++ /dev/null @@ -1,35 +0,0 @@ -// Package units provides helper function to parse and print size and time units -// in human-readable format. -package units - -import ( - "fmt" - "time" -) - -// HumanDuration returns a human-readable approximation of a duration -// (eg. "About a minute", "4 hours ago", etc.). -func HumanDuration(d time.Duration) string { - if seconds := int(d.Seconds()); seconds < 1 { - return "Less than a second" - } else if seconds == 1 { - return "1 second" - } else if seconds < 60 { - return fmt.Sprintf("%d seconds", seconds) - } else if minutes := int(d.Minutes()); minutes == 1 { - return "About a minute" - } else if minutes < 60 { - return fmt.Sprintf("%d minutes", minutes) - } else if hours := int(d.Hours() + 0.5); hours == 1 { - return "About an hour" - } else if hours < 48 { - return fmt.Sprintf("%d hours", hours) - } else if hours < 24*7*2 { - return fmt.Sprintf("%d days", hours/24) - } else if hours < 24*30*2 { - return fmt.Sprintf("%d weeks", hours/24/7) - } else if hours < 24*365*2 { - return fmt.Sprintf("%d months", hours/24/30) - } - return fmt.Sprintf("%d years", int(d.Hours())/24/365) -} diff --git a/vendor/github.com/docker/go-units/size.go b/vendor/github.com/docker/go-units/size.go deleted file mode 100644 index c245a8951..000000000 --- a/vendor/github.com/docker/go-units/size.go +++ /dev/null @@ -1,154 +0,0 @@ -package units - -import ( - "fmt" - "strconv" - "strings" -) - -// See: http://en.wikipedia.org/wiki/Binary_prefix -const ( - // Decimal - - KB = 1000 - MB = 1000 * KB - GB = 1000 * MB - TB = 1000 * GB - PB = 1000 * TB - - // Binary - - KiB = 1024 - MiB = 1024 * KiB - GiB = 1024 * MiB - TiB = 1024 * GiB - PiB = 1024 * TiB -) - -type unitMap map[byte]int64 - -var ( - decimalMap = unitMap{'k': KB, 'm': MB, 'g': GB, 't': TB, 'p': PB} - binaryMap = unitMap{'k': KiB, 'm': MiB, 'g': GiB, 't': TiB, 'p': PiB} -) - -var ( - decimapAbbrs = []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"} - binaryAbbrs = []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"} -) - -func getSizeAndUnit(size float64, base float64, _map []string) (float64, string) { - i := 0 - unitsLimit := len(_map) - 1 - for size >= base && i < unitsLimit { - size = size / base - i++ - } - return size, _map[i] -} - -// CustomSize returns a human-readable approximation of a size -// using custom format. -func CustomSize(format string, size float64, base float64, _map []string) string { - size, unit := getSizeAndUnit(size, base, _map) - return fmt.Sprintf(format, size, unit) -} - -// HumanSizeWithPrecision allows the size to be in any precision, -// instead of 4 digit precision used in units.HumanSize. -func HumanSizeWithPrecision(size float64, precision int) string { - size, unit := getSizeAndUnit(size, 1000.0, decimapAbbrs) - return fmt.Sprintf("%.*g%s", precision, size, unit) -} - -// HumanSize returns a human-readable approximation of a size -// capped at 4 valid numbers (eg. "2.746 MB", "796 KB"). -func HumanSize(size float64) string { - return HumanSizeWithPrecision(size, 4) -} - -// BytesSize returns a human-readable size in bytes, kibibytes, -// mebibytes, gibibytes, or tebibytes (eg. "44kiB", "17MiB"). -func BytesSize(size float64) string { - return CustomSize("%.4g%s", size, 1024.0, binaryAbbrs) -} - -// FromHumanSize returns an integer from a human-readable specification of a -// size using SI standard (eg. "44kB", "17MB"). -func FromHumanSize(size string) (int64, error) { - return parseSize(size, decimalMap) -} - -// RAMInBytes parses a human-readable string representing an amount of RAM -// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and -// returns the number of bytes, or -1 if the string is unparseable. -// Units are case-insensitive, and the 'b' suffix is optional. -func RAMInBytes(size string) (int64, error) { - return parseSize(size, binaryMap) -} - -// Parses the human-readable size string into the amount it represents. -func parseSize(sizeStr string, uMap unitMap) (int64, error) { - // TODO: rewrite to use strings.Cut if there's a space - // once Go < 1.18 is deprecated. - sep := strings.LastIndexAny(sizeStr, "01234567890. ") - if sep == -1 { - // There should be at least a digit. - return -1, fmt.Errorf("invalid size: '%s'", sizeStr) - } - var num, sfx string - if sizeStr[sep] != ' ' { - num = sizeStr[:sep+1] - sfx = sizeStr[sep+1:] - } else { - // Omit the space separator. - num = sizeStr[:sep] - sfx = sizeStr[sep+1:] - } - - size, err := strconv.ParseFloat(num, 64) - if err != nil { - return -1, err - } - // Backward compatibility: reject negative sizes. - if size < 0 { - return -1, fmt.Errorf("invalid size: '%s'", sizeStr) - } - - if len(sfx) == 0 { - return int64(size), nil - } - - // Process the suffix. - - if len(sfx) > 3 { // Too long. - goto badSuffix - } - sfx = strings.ToLower(sfx) - // Trivial case: b suffix. - if sfx[0] == 'b' { - if len(sfx) > 1 { // no extra characters allowed after b. - goto badSuffix - } - return int64(size), nil - } - // A suffix from the map. - if mul, ok := uMap[sfx[0]]; ok { - size *= float64(mul) - } else { - goto badSuffix - } - - // The suffix may have extra "b" or "ib" (e.g. KiB or MB). - switch { - case len(sfx) == 2 && sfx[1] != 'b': - goto badSuffix - case len(sfx) == 3 && sfx[1:] != "ib": - goto badSuffix - } - - return int64(size), nil - -badSuffix: - return -1, fmt.Errorf("invalid suffix: '%s'", sfx) -} diff --git a/vendor/github.com/docker/go-units/ulimit.go b/vendor/github.com/docker/go-units/ulimit.go deleted file mode 100644 index fca0400cc..000000000 --- a/vendor/github.com/docker/go-units/ulimit.go +++ /dev/null @@ -1,123 +0,0 @@ -package units - -import ( - "fmt" - "strconv" - "strings" -) - -// Ulimit is a human friendly version of Rlimit. -type Ulimit struct { - Name string - Hard int64 - Soft int64 -} - -// Rlimit specifies the resource limits, such as max open files. -type Rlimit struct { - Type int `json:"type,omitempty"` - Hard uint64 `json:"hard,omitempty"` - Soft uint64 `json:"soft,omitempty"` -} - -const ( - // magic numbers for making the syscall - // some of these are defined in the syscall package, but not all. - // Also since Windows client doesn't get access to the syscall package, need to - // define these here - rlimitAs = 9 - rlimitCore = 4 - rlimitCPU = 0 - rlimitData = 2 - rlimitFsize = 1 - rlimitLocks = 10 - rlimitMemlock = 8 - rlimitMsgqueue = 12 - rlimitNice = 13 - rlimitNofile = 7 - rlimitNproc = 6 - rlimitRss = 5 - rlimitRtprio = 14 - rlimitRttime = 15 - rlimitSigpending = 11 - rlimitStack = 3 -) - -var ulimitNameMapping = map[string]int{ - //"as": rlimitAs, // Disabled since this doesn't seem usable with the way Docker inits a container. - "core": rlimitCore, - "cpu": rlimitCPU, - "data": rlimitData, - "fsize": rlimitFsize, - "locks": rlimitLocks, - "memlock": rlimitMemlock, - "msgqueue": rlimitMsgqueue, - "nice": rlimitNice, - "nofile": rlimitNofile, - "nproc": rlimitNproc, - "rss": rlimitRss, - "rtprio": rlimitRtprio, - "rttime": rlimitRttime, - "sigpending": rlimitSigpending, - "stack": rlimitStack, -} - -// ParseUlimit parses and returns a Ulimit from the specified string. -func ParseUlimit(val string) (*Ulimit, error) { - parts := strings.SplitN(val, "=", 2) - if len(parts) != 2 { - return nil, fmt.Errorf("invalid ulimit argument: %s", val) - } - - if _, exists := ulimitNameMapping[parts[0]]; !exists { - return nil, fmt.Errorf("invalid ulimit type: %s", parts[0]) - } - - var ( - soft int64 - hard = &soft // default to soft in case no hard was set - temp int64 - err error - ) - switch limitVals := strings.Split(parts[1], ":"); len(limitVals) { - case 2: - temp, err = strconv.ParseInt(limitVals[1], 10, 64) - if err != nil { - return nil, err - } - hard = &temp - fallthrough - case 1: - soft, err = strconv.ParseInt(limitVals[0], 10, 64) - if err != nil { - return nil, err - } - default: - return nil, fmt.Errorf("too many limit value arguments - %s, can only have up to two, `soft[:hard]`", parts[1]) - } - - if *hard != -1 { - if soft == -1 { - return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: soft: -1 (unlimited), hard: %d", *hard) - } - if soft > *hard { - return nil, fmt.Errorf("ulimit soft limit must be less than or equal to hard limit: %d > %d", soft, *hard) - } - } - - return &Ulimit{Name: parts[0], Soft: soft, Hard: *hard}, nil -} - -// GetRlimit returns the RLimit corresponding to Ulimit. -func (u *Ulimit) GetRlimit() (*Rlimit, error) { - t, exists := ulimitNameMapping[u.Name] - if !exists { - return nil, fmt.Errorf("invalid ulimit name %s", u.Name) - } - - return &Rlimit{Type: t, Soft: uint64(u.Soft), Hard: uint64(u.Hard)}, nil -} - -func (u *Ulimit) String() string { - return fmt.Sprintf("%s=%d:%d", u.Name, u.Soft, u.Hard) -} diff --git a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md index 92b78048e..6f24dfff5 100644 --- a/vendor/github.com/emicklei/go-restful/v3/CHANGES.md +++ b/vendor/github.com/emicklei/go-restful/v3/CHANGES.md @@ -1,5 +1,8 @@ # Change history of go-restful +## [v3.12.2] - 2025-02-21 + +- allow empty payloads in post,put,patch, issue #580 ( thanks @liggitt, Jordan Liggitt) ## [v3.12.1] - 2024-05-28 @@ -18,7 +21,7 @@ - fix by restoring custom JSON handler functions (Mike Beaumont #540) -## [v3.12.0] - 2023-08-19 +## [v3.11.0] - 2023-08-19 - restored behavior as <= v3.9.0 with option to change path strategy using TrimRightSlashEnabled. diff --git a/vendor/github.com/emicklei/go-restful/v3/README.md b/vendor/github.com/emicklei/go-restful/v3/README.md index 7234604e4..3fb40d198 100644 --- a/vendor/github.com/emicklei/go-restful/v3/README.md +++ b/vendor/github.com/emicklei/go-restful/v3/README.md @@ -3,7 +3,7 @@ go-restful package for building REST-style Web Services using Google Go [![Go Report Card](https://goreportcard.com/badge/github.com/emicklei/go-restful)](https://goreportcard.com/report/github.com/emicklei/go-restful) -[![GoDoc](https://godoc.org/github.com/emicklei/go-restful?status.svg)](https://pkg.go.dev/github.com/emicklei/go-restful) +[![Go Reference](https://pkg.go.dev/badge/github.com/emicklei/go-restful.svg)](https://pkg.go.dev/github.com/emicklei/go-restful/v3) [![codecov](https://codecov.io/gh/emicklei/go-restful/branch/master/graph/badge.svg)](https://codecov.io/gh/emicklei/go-restful) - [Code examples use v3](https://github.com/emicklei/go-restful/tree/v3/examples) diff --git a/vendor/github.com/emicklei/go-restful/v3/jsr311.go b/vendor/github.com/emicklei/go-restful/v3/jsr311.go index a9b3faaa8..7f04bd905 100644 --- a/vendor/github.com/emicklei/go-restful/v3/jsr311.go +++ b/vendor/github.com/emicklei/go-restful/v3/jsr311.go @@ -65,7 +65,7 @@ func (RouterJSR311) extractParams(pathExpr *pathExpression, matches []string) ma return params } -// http://jsr311.java.net/nonav/releases/1.1/spec/spec3.html#x3-360003.7.2 +// https://download.oracle.com/otndocs/jcp/jaxrs-1.1-mrel-eval-oth-JSpec/ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*Route, error) { candidates := make([]*Route, 0, 8) for i, each := range routes { @@ -126,9 +126,7 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R if trace { traceLogger.Printf("no Route found (from %d) that matches HTTP Content-Type: %s\n", len(previous), contentType) } - if httpRequest.ContentLength > 0 { - return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type") - } + return nil, NewError(http.StatusUnsupportedMediaType, "415: Unsupported Media Type") } // accept @@ -151,20 +149,9 @@ func (r RouterJSR311) detectRoute(routes []Route, httpRequest *http.Request) (*R for _, candidate := range previous { available = append(available, candidate.Produces...) } - // if POST,PUT,PATCH without body - method, length := httpRequest.Method, httpRequest.Header.Get("Content-Length") - if (method == http.MethodPost || - method == http.MethodPut || - method == http.MethodPatch) && (length == "" || length == "0") { - return nil, NewError( - http.StatusUnsupportedMediaType, - fmt.Sprintf("415: Unsupported Media Type\n\nAvailable representations: %s", strings.Join(available, ", ")), - ) - } return nil, NewError( http.StatusNotAcceptable, - fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", ")), - ) + fmt.Sprintf("406: Not Acceptable\n\nAvailable representations: %s", strings.Join(available, ", "))) } // return r.bestMatchByMedia(outputMediaOk, contentType, accept), nil return candidates[0], nil diff --git a/vendor/github.com/emicklei/go-restful/v3/route.go b/vendor/github.com/emicklei/go-restful/v3/route.go index 306c44be7..a2056e2ac 100644 --- a/vendor/github.com/emicklei/go-restful/v3/route.go +++ b/vendor/github.com/emicklei/go-restful/v3/route.go @@ -111,6 +111,8 @@ func (r Route) matchesAccept(mimeTypesWithQuality string) bool { } // Return whether this Route can consume content with a type specified by mimeTypes (can be empty). +// If the route does not specify Consumes then return true (*/*). +// If no content type is set then return true for GET,HEAD,OPTIONS,DELETE and TRACE. func (r Route) matchesContentType(mimeTypes string) bool { if len(r.Consumes) == 0 { diff --git a/vendor/github.com/euank/go-kmsg-parser/kmsgparser/kmsgparser.go b/vendor/github.com/euank/go-kmsg-parser/kmsgparser/kmsgparser.go deleted file mode 100644 index df160cad5..000000000 --- a/vendor/github.com/euank/go-kmsg-parser/kmsgparser/kmsgparser.go +++ /dev/null @@ -1,200 +0,0 @@ -/* -Copyright 2016 Euan Kemp - -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 kmsgparser implements a parser for the Linux `/dev/kmsg` format. -// More information about this format may be found here: -// https://www.kernel.org/doc/Documentation/ABI/testing/dev-kmsg -// Some parts of it are slightly inspired by rsyslog's contrib module: -// https://github.com/rsyslog/rsyslog/blob/v8.22.0/contrib/imkmsg/kmsg.c -package kmsgparser - -import ( - "fmt" - "io" - "os" - "strconv" - "strings" - "syscall" - "time" -) - -// Parser is a parser for the kernel ring buffer found at /dev/kmsg -type Parser interface { - // SeekEnd moves the parser to the end of the kmsg queue. - SeekEnd() error - // Parse provides a channel of messages read from the kernel ring buffer. - // When first called, it will read the existing ringbuffer, after which it will emit new messages as they occur. - Parse() <-chan Message - // SetLogger sets the logger that will be used to report malformed kernel - // ringbuffer lines or unexpected kmsg read errors. - SetLogger(Logger) - // Close closes the underlying kmsg reader for this parser - Close() error -} - -// Message represents a given kmsg logline, including its timestamp (as -// calculated based on offset from boot time), its possibly multi-line body, -// and so on. More information about these mssages may be found here: -// https://www.kernel.org/doc/Documentation/ABI/testing/dev-kmsg -type Message struct { - Priority int - SequenceNumber int - Timestamp time.Time - Message string -} - -func NewParser() (Parser, error) { - f, err := os.Open("/dev/kmsg") - if err != nil { - return nil, err - } - - bootTime, err := getBootTime() - if err != nil { - return nil, err - } - - return &parser{ - log: &StandardLogger{nil}, - kmsgReader: f, - bootTime: bootTime, - }, nil -} - -type ReadSeekCloser interface { - io.ReadCloser - io.Seeker -} - -type parser struct { - log Logger - kmsgReader ReadSeekCloser - bootTime time.Time -} - -func getBootTime() (time.Time, error) { - var sysinfo syscall.Sysinfo_t - err := syscall.Sysinfo(&sysinfo) - if err != nil { - return time.Time{}, fmt.Errorf("could not get boot time: %v", err) - } - // sysinfo only has seconds - return time.Now().Add(-1 * (time.Duration(sysinfo.Uptime) * time.Second)), nil -} - -func (p *parser) SetLogger(log Logger) { - p.log = log -} - -func (p *parser) Close() error { - return p.kmsgReader.Close() -} - -func (p *parser) SeekEnd() error { - _, err := p.kmsgReader.Seek(0, os.SEEK_END) - return err -} - -// Parse will read from the provided reader and provide a channel of messages -// parsed. -// If the provided reader *is not* a proper Linux kmsg device, Parse might not -// behave correctly since it relies on specific behavior of `/dev/kmsg` -// -// A goroutine is created to process the provided reader. The goroutine will -// exit when the given reader is closed. -// Closing the passed in reader will cause the goroutine to exit. -func (p *parser) Parse() <-chan Message { - - output := make(chan Message, 1) - - go func() { - defer close(output) - msg := make([]byte, 8192) - for { - // Each read call gives us one full message. - // https://www.kernel.org/doc/Documentation/ABI/testing/dev-kmsg - n, err := p.kmsgReader.Read(msg) - if err != nil { - if err == syscall.EPIPE { - p.log.Warningf("short read from kmsg; skipping") - continue - } - - if err == io.EOF { - p.log.Infof("kmsg reader closed, shutting down") - return - } - - p.log.Errorf("error reading /dev/kmsg: %v", err) - return - } - - msgStr := string(msg[:n]) - - message, err := p.parseMessage(msgStr) - if err != nil { - p.log.Warningf("unable to parse kmsg message %q: %v", msgStr, err) - continue - } - - output <- message - } - }() - - return output -} - -func (p *parser) parseMessage(input string) (Message, error) { - // Format: - // PRIORITY,SEQUENCE_NUM,TIMESTAMP,-;MESSAGE - parts := strings.SplitN(input, ";", 2) - if len(parts) != 2 { - return Message{}, fmt.Errorf("invalid kmsg; must contain a ';'") - } - - metadata, message := parts[0], parts[1] - - metadataParts := strings.Split(metadata, ",") - if len(metadataParts) < 3 { - return Message{}, fmt.Errorf("invalid kmsg: must contain at least 3 ',' separated pieces at the start") - } - - priority, sequence, timestamp := metadataParts[0], metadataParts[1], metadataParts[2] - - prioNum, err := strconv.Atoi(priority) - if err != nil { - return Message{}, fmt.Errorf("could not parse %q as priority: %v", priority, err) - } - - sequenceNum, err := strconv.Atoi(sequence) - if err != nil { - return Message{}, fmt.Errorf("could not parse %q as sequence number: %v", priority, err) - } - - timestampUsFromBoot, err := strconv.ParseInt(timestamp, 10, 64) - if err != nil { - return Message{}, fmt.Errorf("could not parse %q as timestamp: %v", priority, err) - } - // timestamp is offset in microsecond from boottime. - msgTime := p.bootTime.Add(time.Duration(timestampUsFromBoot) * time.Microsecond) - - return Message{ - Priority: prioNum, - SequenceNumber: sequenceNum, - Timestamp: msgTime, - Message: message, - }, nil -} diff --git a/vendor/github.com/euank/go-kmsg-parser/kmsgparser/log.go b/vendor/github.com/euank/go-kmsg-parser/kmsgparser/log.go deleted file mode 100644 index 6ea2d96df..000000000 --- a/vendor/github.com/euank/go-kmsg-parser/kmsgparser/log.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2016 Euan Kemp - -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 kmsgparser - -import stdlog "log" - -// Logger is a glog compatible logging interface -// The StandardLogger struct can be used to wrap a log.Logger from the golang -// "log" package to create a standard a logger fulfilling this interface as -// well. -type Logger interface { - Warningf(string, ...interface{}) - Infof(string, ...interface{}) - Errorf(string, ...interface{}) -} - -// StandardLogger adapts the "log" package's Logger interface to be a Logger -type StandardLogger struct { - *stdlog.Logger -} - -func (s *StandardLogger) Warningf(fmt string, args ...interface{}) { - if s.Logger == nil { - return - } - s.Logger.Printf("[WARNING] "+fmt, args) -} - -func (s *StandardLogger) Infof(fmt string, args ...interface{}) { - if s.Logger == nil { - return - } - s.Logger.Printf("[INFO] "+fmt, args) -} - -func (s *StandardLogger) Errorf(fmt string, args ...interface{}) { - if s.Logger == nil { - return - } - s.Logger.Printf("[INFO] "+fmt, args) -} diff --git a/vendor/github.com/fxamacker/cbor/v2/README.md b/vendor/github.com/fxamacker/cbor/v2/README.md index af0a79507..d072b81c7 100644 --- a/vendor/github.com/fxamacker/cbor/v2/README.md +++ b/vendor/github.com/fxamacker/cbor/v2/README.md @@ -1,30 +1,31 @@ -# CBOR Codec in Go - - +

CBOR Codec Go logo

[fxamacker/cbor](https://github.com/fxamacker/cbor) is a library for encoding and decoding [CBOR](https://www.rfc-editor.org/info/std94) and [CBOR Sequences](https://www.rfc-editor.org/rfc/rfc8742.html). CBOR is a [trusted alternative](https://www.rfc-editor.org/rfc/rfc8949.html#name-comparison-of-other-binary-) to JSON, MessagePack, Protocol Buffers, etc.  CBOR is an Internet Standard defined by [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94) and is designed to be relevant for decades. -`fxamacker/cbor` is used in projects by Arm Ltd., Cisco, EdgeX Foundry, Flow Foundation, Fraunhofer‑AISEC, Kubernetes, Let's Encrypt (ISRG), Linux Foundation, Microsoft, Mozilla, Oasis Protocol, Tailscale, Teleport, [etc](https://github.com/fxamacker/cbor#who-uses-fxamackercbor). +`fxamacker/cbor` is used in projects by Arm Ltd., EdgeX Foundry, Flow Foundation, Fraunhofer‑AISEC, IBM, Kubernetes[*](https://github.com/search?q=org%3Akubernetes%20fxamacker%2Fcbor&type=code), Let's Encrypt, Linux Foundation, Microsoft, Oasis Protocol, Red Hat[*](https://github.com/search?q=org%3Aopenshift+fxamacker%2Fcbor&type=code), Tailscale[*](https://github.com/search?q=org%3Atailscale+fxamacker%2Fcbor&type=code), Veraison[*](https://github.com/search?q=org%3Averaison+fxamacker%2Fcbor&type=code), [etc](https://github.com/fxamacker/cbor#who-uses-fxamackercbor). -See [Quick Start](#quick-start) and [Releases](https://github.com/fxamacker/cbor/releases/). 🆕 `UnmarshalFirst` and `DiagnoseFirst` can decode CBOR Sequences. `cbor.MarshalToBuffer()` and `UserBufferEncMode` accepts user-specified buffer. +See [Quick Start](#quick-start) and [Releases](https://github.com/fxamacker/cbor/releases/). 🆕 `UnmarshalFirst` and `DiagnoseFirst` can decode CBOR Sequences. `MarshalToBuffer` and `UserBufferEncMode` accepts user-specified buffer. ## fxamacker/cbor [![](https://github.com/fxamacker/cbor/workflows/ci/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3Aci) -[![](https://github.com/fxamacker/cbor/workflows/cover%20%E2%89%A596%25/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3A%22cover+%E2%89%A596%25%22) +[![](https://github.com/fxamacker/cbor/workflows/cover%20%E2%89%A597%25/badge.svg)](https://github.com/fxamacker/cbor/actions?query=workflow%3A%22cover+%E2%89%A597%25%22) [![CodeQL](https://github.com/fxamacker/cbor/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/fxamacker/cbor/actions/workflows/codeql-analysis.yml) [![](https://img.shields.io/badge/fuzzing-passing-44c010)](#fuzzing-and-code-coverage) [![Go Report Card](https://goreportcard.com/badge/github.com/fxamacker/cbor)](https://goreportcard.com/report/github.com/fxamacker/cbor) +[![](https://img.shields.io/ossf-scorecard/github.com/fxamacker/cbor?label=openssf%20scorecard)](https://github.com/fxamacker/cbor#fuzzing-and-code-coverage) `fxamacker/cbor` is a CBOR codec in full conformance with [IETF STD 94 (RFC 8949)](https://www.rfc-editor.org/info/std94). It also supports CBOR Sequences ([RFC 8742](https://www.rfc-editor.org/rfc/rfc8742.html)) and Extended Diagnostic Notation ([Appendix G of RFC 8610](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G)). Features include full support for CBOR tags, [Core Deterministic Encoding](https://www.rfc-editor.org/rfc/rfc8949.html#name-core-deterministic-encoding), duplicate map key detection, etc. +API is mostly same as `encoding/json`, plus interfaces that simplify concurrency and CBOR options. + Design balances trade-offs between security, speed, concurrency, encoded data size, usability, etc. -
Highlights

+

🔎  Highlights

__🚀  Speed__ @@ -38,7 +39,7 @@ Codec passed multiple confidential security assessments in 2022. No vulnerabili __🗜️  Data Size__ -Struct tags (`toarray`, `keyasint`, `omitempty`) automatically reduce size of encoded structs. Encoding optionally shrinks float64→32→16 when values fit. +Struct tag options (`toarray`, `keyasint`, `omitempty`, `omitzero`) and field tag "-" automatically reduce size of encoded structs. Encoding optionally shrinks float64→32→16 when values fit. __:jigsaw:  Usability__ @@ -58,164 +59,205 @@ Features include CBOR [extension points](https://www.rfc-editor.org/rfc/rfc8949. `fxamacker/cbor` has configurable limits, etc. that defend against malicious CBOR data. -By contrast, `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security). - -

Example decoding with encoding/gob 💥 fatal error (out of memory)

- -```Go -// Example of encoding/gob having "fatal error: runtime: out of memory" -// while decoding 181 bytes. -package main -import ( - "bytes" - "encoding/gob" - "encoding/hex" - "fmt" -) - -// Example data is from https://github.com/golang/go/issues/24446 -// (shortened to 181 bytes). -const data = "4dffb503010102303001ff30000109010130010800010130010800010130" + - "01ffb80001014a01ffb60001014b01ff860001013001ff860001013001ff" + - "860001013001ff860001013001ffb80000001eff850401010e3030303030" + - "30303030303030303001ff3000010c0104000016ffb70201010830303030" + - "3030303001ff3000010c000030ffb6040405fcff00303030303030303030" + - "303030303030303030303030303030303030303030303030303030303030" + - "30" - -type X struct { - J *X - K map[string]int -} - -func main() { - raw, _ := hex.DecodeString(data) - decoder := gob.NewDecoder(bytes.NewReader(raw)) - - var x X - decoder.Decode(&x) // fatal error: runtime: out of memory - fmt.Println("Decoding finished.") -} -``` - -


- -
- -`fxamacker/cbor` is fast at rejecting malformed CBOR data. E.g. attempts to -decode 10 bytes of malicious CBOR data to `[]byte` (with default settings): - -| Codec | Speed (ns/op) | Memory | Allocs | -| :---- | ------------: | -----: | -----: | -| fxamacker/cbor 2.5.0 | 44 ± 5% | 32 B/op | 2 allocs/op | -| ugorji/go 1.2.11 | 5353261 ± 4% | 67111321 B/op | 13 allocs/op | - -
Benchmark details

- -Latest comparison used: -- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` -- go1.19.10, linux/amd64, i5-13600K (disabled all e-cores, DDR4 @2933) -- go test -bench=. -benchmem -count=20 - -#### Prior comparisons - -| Codec | Speed (ns/op) | Memory | Allocs | -| :---- | ------------: | -----: | -----: | -| fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op | -| fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op | -| ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op | -| ugorji/go 1.1.0 - 1.2.6 | 💥 runtime: | out of memory: | cannot allocate | - -- Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` -- go1.19.6, linux/amd64, i5-13600K (DDR4) -- go test -bench=. -benchmem -count=20 - -


- -
- -### Smaller Encodings with Struct Tags - -Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs. - -
Example encoding 3-level nested Go struct to 1 byte CBOR

- -https://go.dev/play/p/YxwvfPdFQG2 - -```Go -// Example encoding nested struct (with omitempty tag) -// - encoding/json: 18 byte JSON -// - fxamacker/cbor: 1 byte CBOR -package main - -import ( - "encoding/hex" - "encoding/json" - "fmt" - - "github.com/fxamacker/cbor/v2" -) - -type GrandChild struct { - Quux int `json:",omitempty"` -} - -type Child struct { - Baz int `json:",omitempty"` - Qux GrandChild `json:",omitempty"` -} - -type Parent struct { - Foo Child `json:",omitempty"` - Bar int `json:",omitempty"` -} - -func cb() { - results, _ := cbor.Marshal(Parent{}) - fmt.Println("hex(CBOR): " + hex.EncodeToString(results)) - - text, _ := cbor.Diagnose(results) // Diagnostic Notation - fmt.Println("DN: " + text) -} - -func js() { - results, _ := json.Marshal(Parent{}) - fmt.Println("hex(JSON): " + hex.EncodeToString(results)) - - text := string(results) // JSON - fmt.Println("JSON: " + text) -} - -func main() { - cb() - fmt.Println("-------------") - js() -} -``` - -Output (DN is Diagnostic Notation): -``` -hex(CBOR): a0 -DN: {} -------------- -hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d -JSON: {"Foo":{"Qux":{}}} -``` - -


- -
- -Example using different struct tags together: +Notably, `fxamacker/cbor` is fast at rejecting malformed CBOR data. + +> [!NOTE] +> Benchmarks rejecting 10 bytes of malicious CBOR data decoding to `[]byte`: +> +> | Codec | Speed (ns/op) | Memory | Allocs | +> | :---- | ------------: | -----: | -----: | +> | fxamacker/cbor 2.7.0 | 47 ± 7% | 32 B/op | 2 allocs/op | +> | ugorji/go 1.2.12 | 5878187 ± 3% | 67111556 B/op | 13 allocs/op | +> +> Faster hardware (overclocked DDR4 or DDR5) can reduce speed difference. +> +>
🔎  Benchmark details

+> +> Latest comparison for decoding CBOR data to Go `[]byte`: +> - Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` +> - go1.22.7, linux/amd64, i5-13600K (DDR4-2933, disabled e-cores) +> - go test -bench=. -benchmem -count=20 +> +> #### Prior comparisons +> +> | Codec | Speed (ns/op) | Memory | Allocs | +> | :---- | ------------: | -----: | -----: | +> | fxamacker/cbor 2.5.0-beta2 | 44.33 ± 2% | 32 B/op | 2 allocs/op | +> | fxamacker/cbor 0.1.0 - 2.4.0 | ~44.68 ± 6% | 32 B/op | 2 allocs/op | +> | ugorji/go 1.2.10 | 5524792.50 ± 3% | 67110491 B/op | 12 allocs/op | +> | ugorji/go 1.1.0 - 1.2.6 | 💥 runtime: | out of memory: | cannot allocate | +> +> - Input: `[]byte{0x9B, 0x00, 0x00, 0x42, 0xFA, 0x42, 0xFA, 0x42, 0xFA, 0x42}` +> - go1.19.6, linux/amd64, i5-13600K (DDR4) +> - go test -bench=. -benchmem -count=20 +> +>

+ +In contrast, some codecs can crash or use excessive resources while decoding bad data. + +> [!WARNING] +> Go's `encoding/gob` is [not designed to be hardened against adversarial inputs](https://pkg.go.dev/encoding/gob#hdr-Security). +> +>
🔎  gob fatal error (out of memory) 💥 decoding 181 bytes

+> +> ```Go +> // Example of encoding/gob having "fatal error: runtime: out of memory" +> // while decoding 181 bytes (all Go versions as of Dec. 8, 2024). +> package main +> import ( +> "bytes" +> "encoding/gob" +> "encoding/hex" +> "fmt" +> ) +> +> // Example data is from https://github.com/golang/go/issues/24446 +> // (shortened to 181 bytes). +> const data = "4dffb503010102303001ff30000109010130010800010130010800010130" + +> "01ffb80001014a01ffb60001014b01ff860001013001ff860001013001ff" + +> "860001013001ff860001013001ffb80000001eff850401010e3030303030" + +> "30303030303030303001ff3000010c0104000016ffb70201010830303030" + +> "3030303001ff3000010c000030ffb6040405fcff00303030303030303030" + +> "303030303030303030303030303030303030303030303030303030303030" + +> "30" +> +> type X struct { +> J *X +> K map[string]int +> } +> +> func main() { +> raw, _ := hex.DecodeString(data) +> decoder := gob.NewDecoder(bytes.NewReader(raw)) +> +> var x X +> decoder.Decode(&x) // fatal error: runtime: out of memory +> fmt.Println("Decoding finished.") +> } +> ``` +> +> +>

+ +### Smaller Encodings with Struct Tag Options + +Struct tags automatically reduce encoded size of structs and improve speed. + +We can write less code by using struct tag options: +- `toarray`: encode without field names (decode back to original struct) +- `keyasint`: encode field names as integers (decode back to original struct) +- `omitempty`: omit empty field when encoding +- `omitzero`: omit zero-value field when encoding + +As a special case, struct field tag "-" omits the field. + +NOTE: When a struct uses `toarray`, the encoder will ignore `omitempty` and `omitzero` to prevent position of encoded array elements from changing. This allows decoder to match encoded elements to their Go struct field. ![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags") -API is mostly same as `encoding/json`, plus interfaces that simplify concurrency for CBOR options. +> [!NOTE] +> `fxamacker/cbor` can encode a 3-level nested Go struct to 1 byte! +> - `encoding/json`: 18 bytes of JSON +> - `fxamacker/cbor`: 1 byte of CBOR +> +>
🔎  Encoding 3-level nested Go struct with omitempty

+> +> https://go.dev/play/p/YxwvfPdFQG2 +> +> ```Go +> // Example encoding nested struct (with omitempty tag) +> // - encoding/json: 18 byte JSON +> // - fxamacker/cbor: 1 byte CBOR +> +> package main +> +> import ( +> "encoding/hex" +> "encoding/json" +> "fmt" +> +> "github.com/fxamacker/cbor/v2" +> ) +> +> type GrandChild struct { +> Quux int `json:",omitempty"` +> } +> +> type Child struct { +> Baz int `json:",omitempty"` +> Qux GrandChild `json:",omitempty"` +> } +> +> type Parent struct { +> Foo Child `json:",omitempty"` +> Bar int `json:",omitempty"` +> } +> +> func cb() { +> results, _ := cbor.Marshal(Parent{}) +> fmt.Println("hex(CBOR): " + hex.EncodeToString(results)) +> +> text, _ := cbor.Diagnose(results) // Diagnostic Notation +> fmt.Println("DN: " + text) +> } +> +> func js() { +> results, _ := json.Marshal(Parent{}) +> fmt.Println("hex(JSON): " + hex.EncodeToString(results)) +> +> text := string(results) // JSON +> fmt.Println("JSON: " + text) +> } +> +> func main() { +> cb() +> fmt.Println("-------------") +> js() +> } +> ``` +> +> Output (DN is Diagnostic Notation): +> ``` +> hex(CBOR): a0 +> DN: {} +> ------------- +> hex(JSON): 7b22466f6f223a7b22517578223a7b7d7d7d +> JSON: {"Foo":{"Qux":{}}} +> ``` +> +>

+ ## Quick Start __Install__: `go get github.com/fxamacker/cbor/v2` and `import "github.com/fxamacker/cbor/v2"`. +> [!TIP] +> +> Tinygo users can try beta/experimental branch [feature/cbor-tinygo-beta](https://github.com/fxamacker/cbor/tree/feature/cbor-tinygo-beta). +> +>
🔎  More about tinygo feature branch +> +> ### Tinygo +> +> Branch [feature/cbor-tinygo-beta](https://github.com/fxamacker/cbor/tree/feature/cbor-tinygo-beta) is based on fxamacker/cbor v2.7.0 and it can be compiled using tinygo v0.33 (also compiles with golang/go). +> +> It passes unit tests (with both go1.22 and tinygo v0.33) and is considered beta/experimental for tinygo. +> +> :warning: The `feature/cbor-tinygo-beta` branch does not get fuzz tested yet. +> +> Changes in this feature branch only affect tinygo compiled software. Summary of changes: +> - default `DecOptions.MaxNestedLevels` is reduced to 16 (was 32). User can specify higher limit but 24+ crashes tests when compiled with tinygo v0.33. +> - disabled decoding CBOR tag data to Go interface because tinygo v0.33 is missing needed feature. +> - encoding error message can be different when encoding function type. +> +> Related tinygo issues: +> - https://github.com/tinygo-org/tinygo/issues/4277 +> - https://github.com/tinygo-org/tinygo/issues/4458 +> +>
+ + ### Key Points This library can encode and decode CBOR (RFC 8949) and CBOR Sequences (RFC 8742). @@ -252,16 +294,17 @@ rest, err = cbor.UnmarshalFirst(b, &v) // decode []byte b to v // DiagnoseFirst translates first CBOR data item to text and returns remaining bytes. text, rest, err = cbor.DiagnoseFirst(b) // decode []byte b to Diagnostic Notation text -// NOTE: Unmarshal returns ExtraneousDataError if there are remaining bytes, -// but new funcs UnmarshalFirst and DiagnoseFirst do not. +// NOTE: Unmarshal() returns ExtraneousDataError if there are remaining bytes, but +// UnmarshalFirst() and DiagnoseFirst() allow trailing bytes. ``` -__IMPORTANT__: 👉 CBOR settings allow trade-offs between speed, security, encoding size, etc. - -- Different CBOR libraries may use different default settings. -- CBOR-based formats or protocols usually require specific settings. - -For example, WebAuthn uses "CTAP2 Canonical CBOR" which is available as a preset. +> [!IMPORTANT] +> CBOR settings allow trade-offs between speed, security, encoding size, etc. +> +> - Different CBOR libraries may use different default settings. +> - CBOR-based formats or protocols usually require specific settings. +> +> For example, WebAuthn uses "CTAP2 Canonical CBOR" which is available as a preset. ### Presets @@ -312,9 +355,63 @@ err = em.MarshalToBuffer(v, &buf) // encode v to provided buf ### Struct Tags -Struct tags (`toarray`, `keyasint`, `omitempty`) reduce encoded size of structs. +Struct tag options (`toarray`, `keyasint`, `omitempty`, `omitzero`) reduce encoded size of structs. + +As a special case, struct field tag "-" omits the field. + +
🔎  Example encoding with struct field tag "-"

+ +https://go.dev/play/p/aWEIFxd7InX + +```Go +// https://github.com/fxamacker/cbor/issues/652 +package main + +import ( + "encoding/json" + "fmt" + + "github.com/fxamacker/cbor/v2" +) + +// The `cbor:"-"` tag omits the Type field when encoding to CBOR. +type Entity struct { + _ struct{} `cbor:",toarray"` + ID uint64 `json:"id"` + Type string `cbor:"-" json:"typeOf"` + Name string `json:"name"` +} + +func main() { + entity := Entity{ + ID: 1, + Type: "int64", + Name: "Identifier", + } + + c, _ := cbor.Marshal(entity) + diag, _ := cbor.Diagnose(c) + fmt.Printf("CBOR in hex: %x\n", c) + fmt.Printf("CBOR in edn: %s\n", diag) + + j, _ := json.Marshal(entity) + fmt.Printf("JSON: %s\n", string(j)) + + fmt.Printf("JSON encoding is %d bytes\n", len(j)) + fmt.Printf("CBOR encoding is %d bytes\n", len(c)) + + // Output: + // CBOR in hex: 82016a4964656e746966696572 + // CBOR in edn: [1, "Identifier"] + // JSON: {"id":1,"typeOf":"int64","name":"Identifier"} + // JSON encoding is 45 bytes + // CBOR encoding is 13 bytes +} +``` + +

-
Example encoding 3-level nested Go struct to 1 byte CBOR

+

🔎  Example encoding 3-level nested Go struct to 1 byte CBOR

https://go.dev/play/p/YxwvfPdFQG2 @@ -382,13 +479,13 @@ JSON: {"Foo":{"Qux":{}}}

-
Example using several struct tags

+

🔎  Example using struct tag options

![alt text](https://github.com/fxamacker/images/raw/master/cbor/v2.3.0/cbor_struct_tags_api.svg?sanitize=1 "CBOR API and Go Struct Tags")

-Struct tags simplify use of CBOR-based protocols that require CBOR arrays or maps with integer keys. +Struct tag options simplify use of CBOR-based protocols that require CBOR arrays or maps with integer keys. ### CBOR Tags @@ -404,7 +501,7 @@ em, err := opts.EncModeWithSharedTags(ts) // mutable shared CBOR tags `TagSet` and modes using it are safe for concurrent use. Equivalent API is available for `DecMode`. -
Example using TagSet and TagOptions

+

🔎  Example using TagSet and TagOptions

```go // Use signedCWT struct defined in "Decoding CWT" example. @@ -430,16 +527,149 @@ if err := dm.Unmarshal(data, &v); err != nil { em, _ := cbor.EncOptions{}.EncModeWithTags(tags) // Marshal signedCWT with tag number. -if data, err := cbor.Marshal(v); err != nil { +if data, err := em.Marshal(v); err != nil { return err } ```

+👉 `fxamacker/cbor` allows user apps to use almost any current or future CBOR tag number by implementing `cbor.Marshaler` and `cbor.Unmarshaler` interfaces. + +Basically, `MarshalCBOR` and `UnmarshalCBOR` functions can be implemented by user apps and those functions will automatically be called by this CBOR codec's `Marshal`, `Unmarshal`, etc. + +The following [example](https://github.com/fxamacker/cbor/blob/master/example_embedded_json_tag_for_cbor_test.go) shows how to encode and decode a tagged CBOR data item with tag number 262. The tag content is a JSON object "embedded" as a CBOR byte string (major type 2). + +
🔎  Example using Embedded JSON Tag for CBOR (tag 262) + +```go +// https://github.com/fxamacker/cbor/issues/657 + +package cbor_test + +// NOTE: RFC 8949 does not mention tag number 262. IANA assigned +// CBOR tag number 262 as "Embedded JSON Object" specified by the +// document Embedded JSON Tag for CBOR: +// +// "Tag 262 can be applied to a byte string (major type 2) to indicate +// that the byte string is a JSON Object. The length of the byte string +// indicates the content." +// +// For more info, see Embedded JSON Tag for CBOR at: +// https://github.com/toravir/CBOR-Tag-Specs/blob/master/embeddedJSON.md + +import ( + "bytes" + "encoding/json" + "fmt" + + "github.com/fxamacker/cbor/v2" +) + +// cborTagNumForEmbeddedJSON is the CBOR tag number 262. +const cborTagNumForEmbeddedJSON = 262 + +// EmbeddedJSON represents a Go value to be encoded as a tagged CBOR data item +// with tag number 262 and the tag content is a JSON object "embedded" as a +// CBOR byte string (major type 2). +type EmbeddedJSON struct { + any +} + +func NewEmbeddedJSON(val any) EmbeddedJSON { + return EmbeddedJSON{val} +} + +// MarshalCBOR encodes EmbeddedJSON to a tagged CBOR data item with the +// tag number 262 and the tag content is a JSON object that is +// "embedded" as a CBOR byte string. +func (v EmbeddedJSON) MarshalCBOR() ([]byte, error) { + // Encode v to JSON object. + data, err := json.Marshal(v) + if err != nil { + return nil, err + } + + // Create cbor.Tag representing a tagged CBOR data item. + tag := cbor.Tag{ + Number: cborTagNumForEmbeddedJSON, + Content: data, + } + + // Marshal to a tagged CBOR data item. + return cbor.Marshal(tag) +} + +// UnmarshalCBOR decodes a tagged CBOR data item to EmbeddedJSON. +// The byte slice provided to this function must contain a single +// tagged CBOR data item with the tag number 262 and tag content +// must be a JSON object "embedded" as a CBOR byte string. +func (v *EmbeddedJSON) UnmarshalCBOR(b []byte) error { + // Unmarshal tagged CBOR data item. + var tag cbor.Tag + if err := cbor.Unmarshal(b, &tag); err != nil { + return err + } + + // Check tag number. + if tag.Number != cborTagNumForEmbeddedJSON { + return fmt.Errorf("got tag number %d, expect tag number %d", tag.Number, cborTagNumForEmbeddedJSON) + } + + // Check tag content. + jsonData, isByteString := tag.Content.([]byte) + if !isByteString { + return fmt.Errorf("got tag content type %T, expect tag content []byte", tag.Content) + } + + // Unmarshal JSON object. + return json.Unmarshal(jsonData, v) +} + +// MarshalJSON encodes EmbeddedJSON to a JSON object. +func (v EmbeddedJSON) MarshalJSON() ([]byte, error) { + return json.Marshal(v.any) +} + +// UnmarshalJSON decodes a JSON object. +func (v *EmbeddedJSON) UnmarshalJSON(b []byte) error { + dec := json.NewDecoder(bytes.NewReader(b)) + dec.UseNumber() + return dec.Decode(&v.any) +} + +func Example_embeddedJSONTagForCBOR() { + value := NewEmbeddedJSON(map[string]any{ + "name": "gopher", + "id": json.Number("42"), + }) + + data, err := cbor.Marshal(value) + if err != nil { + panic(err) + } + + fmt.Printf("cbor: %x\n", data) + + var v EmbeddedJSON + err = cbor.Unmarshal(data, &v) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", v.any) + for k, v := range v.any.(map[string]any) { + fmt.Printf(" %s: %v (%T)\n", k, v, v) + } +} +``` + +
+ + ### Functions and Interfaces -
Functions and interfaces at a glance

+

🔎  Functions and interfaces at a glance

Common functions with same API as `encoding/json`: - `Marshal`, `Unmarshal` @@ -453,7 +683,7 @@ because RFC 8949 treats CBOR data item with remaining bytes as malformed. Other useful functions: - `Diagnose`, `DiagnoseFirst` produce human-readable [Extended Diagnostic Notation](https://www.rfc-editor.org/rfc/rfc8610.html#appendix-G) from CBOR data. - `UnmarshalFirst` decodes first CBOR data item and return any remaining bytes. -- `Wellformed` returns true if the the CBOR data item is well-formed. +- `Wellformed` returns true if the CBOR data item is well-formed. Interfaces identical or comparable to Go `encoding` packages include: `Marshaler`, `Unmarshaler`, `BinaryMarshaler`, and `BinaryUnmarshaler`. @@ -472,15 +702,28 @@ Default limits may need to be increased for systems handling very large data (e. ## Status -v2.7.0 (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. +[v2.9.0](https://github.com/fxamacker/cbor/releases/tag/v2.9.0) (Jul 13, 2025) improved interoperability/transcoding between CBOR & JSON, refactored tests, and improved docs. +- Add opt-in support for `encoding.TextMarshaler` and `encoding.TextUnmarshaler` to encode and decode from CBOR text string. +- Add opt-in support for `json.Marshaler` and `json.Unmarshaler` via user-provided transcoding function. +- Update docs for TimeMode, Tag, RawTag, and add example for Embedded JSON Tag for CBOR. + +v2.9.0 passed fuzz tests and is production quality. + +The minimum version of Go required to build: +- v2.8.0 and newer releases require go 1.20+. +- v2.7.1 and older releases require go 1.17+. For more details, see [release notes](https://github.com/fxamacker/cbor/releases). -### Prior Release +### Prior Releases + +[v2.8.0](https://github.com/fxamacker/cbor/releases/tag/v2.8.0) (March 30, 2025) is a small release primarily to add `omitzero` option to struct field tags and fix bugs. It passed fuzz tests (billions of executions) and is production quality. + +[v2.7.0](https://github.com/fxamacker/cbor/releases/tag/v2.7.0) (June 23, 2024) adds features and improvements that help large projects (e.g. Kubernetes) use CBOR as an alternative to JSON and Protocol Buffers. Other improvements include speedups, improved memory use, bug fixes, new serialization options, etc. It passed fuzz tests (5+ billion executions) and is production quality. [v2.6.0](https://github.com/fxamacker/cbor/releases/tag/v2.6.0) (February 2024) adds important new features, optimizations, and bug fixes. It is especially useful to systems that need to convert data between CBOR and JSON. New options and optimizations improve handling of bignum, integers, maps, and strings. -v2.5.0 was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). +[v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) was released on Sunday, August 13, 2023 with new features and important bug fixes. It is fuzz tested and production quality after extended beta [v2.5.0-beta](https://github.com/fxamacker/cbor/releases/tag/v2.5.0-beta) (Dec 2022) -> [v2.5.0](https://github.com/fxamacker/cbor/releases/tag/v2.5.0) (Aug 2023). __IMPORTANT__: 👉 Before upgrading from v2.4 or older release, please read the notable changes highlighted in the release notes. v2.5.0 is a large release with bug fixes to error handling for extraneous data in `Unmarshal`, etc. that should be reviewed before upgrading. @@ -489,7 +732,7 @@ See [v2.5.0 release notes](https://github.com/fxamacker/cbor/releases/tag/v2.5.0 See ["Version and API Changes"](https://github.com/fxamacker/cbor#versions-and-api-changes) section for more info about version numbering, etc. Do the allocation by running takeByTopologyNUMAPacked() over the -// available CPUs in that NUMA node and return -// -// Otherwise, for each pair of NUMA nodes: -// - If the set of requested CPUs (modulo 2) can be evenly split across -// the 2 NUMA nodes; AND -// - Any remaining CPUs (after the modulo operation) can be striped across -// some subset of the NUMA nodes; -// --> Do the allocation by running takeByTopologyNUMAPacked() over the -// available CPUs in both NUMA nodes and return -// -// Otherwise, for each 3-tuple of NUMA nodes: -// - If the set of requested CPUs (modulo 3) can be evenly distributed -// across the 3 NUMA nodes; AND -// - Any remaining CPUs (after the modulo operation) can be striped across -// some subset of the NUMA nodes; -// --> Do the allocation by running takeByTopologyNUMAPacked() over the -// available CPUs in all three NUMA nodes and return -// -// ... -// -// Otherwise, for the set of all NUMA nodes: -// - If the set of requested CPUs (modulo NUM_NUMA_NODES) can be evenly -// distributed across all NUMA nodes; AND -// - Any remaining CPUs (after the modulo operation) can be striped across -// some subset of the NUMA nodes; -// --> Do the allocation by running takeByTopologyNUMAPacked() over the -// available CPUs in all NUMA nodes and return -// -// If none of the above conditions can be met, then resort back to a -// best-effort fit of packing CPUs into NUMA nodes by calling -// takeByTopologyNUMAPacked() over all available CPUs. -// -// NOTE: A "balance score" will be calculated to help find the best subset of -// NUMA nodes to allocate any 'remainder' CPUs from (in cases where the total -// number of CPUs to allocate cannot be evenly distributed across the chosen -// set of NUMA nodes). This "balance score" is calculated as the standard -// deviation of how many CPUs will be available on each NUMA node after all -// evenly distributed and remainder CPUs are allocated. The subset with the -// lowest "balance score" will receive the CPUs in order to keep the overall -// allocation of CPUs as "balanced" as possible. -// -// NOTE: This algorithm has been generalized to take an additional -// 'cpuGroupSize' parameter to ensure that CPUs are always allocated in groups -// of size 'cpuGroupSize' according to the algorithm described above. This is -// important, for example, to ensure that all CPUs (i.e. all hyperthreads) from -// a single core are allocated together. -func takeByTopologyNUMADistributed(topo *topology.CPUTopology, availableCPUs cpuset.CPUSet, numCPUs int, cpuGroupSize int, cpuSortingStrategy CPUSortingStrategy) (cpuset.CPUSet, error) { - // If the number of CPUs requested cannot be handed out in chunks of - // 'cpuGroupSize', then we just call out the packing algorithm since we - // can't distribute CPUs in this chunk size. - // PreferAlignByUncoreCache feature not implemented here yet and set to false. - // Support for PreferAlignByUncoreCache to be done at beta release. - if (numCPUs % cpuGroupSize) != 0 { - return takeByTopologyNUMAPacked(topo, availableCPUs, numCPUs, cpuSortingStrategy, false) - } - - // Otherwise build an accumulator to start allocating CPUs from. - acc := newCPUAccumulator(topo, availableCPUs, numCPUs, cpuSortingStrategy) - if acc.isSatisfied() { - return acc.result, nil - } - if acc.isFailed() { - return cpuset.New(), fmt.Errorf("not enough cpus available to satisfy request: requested=%d, available=%d", numCPUs, availableCPUs.Size()) - } - - // Get the list of NUMA nodes represented by the set of CPUs in 'availableCPUs'. - numas := acc.sortAvailableNUMANodes() - - // Calculate the minimum and maximum possible number of NUMA nodes that - // could satisfy this request. This is used to optimize how many iterations - // of the loop we need to go through below. - minNUMAs, maxNUMAs := acc.rangeNUMANodesNeededToSatisfy(cpuGroupSize) - - // Try combinations of 1,2,3,... NUMA nodes until we find a combination - // where we can evenly distribute CPUs across them. To optimize things, we - // don't always start at 1 and end at len(numas). Instead, we use the - // values of 'minNUMAs' and 'maxNUMAs' calculated above. - for k := minNUMAs; k <= maxNUMAs; k++ { - // Iterate through the various n-choose-k NUMA node combinations, - // looking for the combination of NUMA nodes that can best have CPUs - // distributed across them. - var bestBalance float64 = math.MaxFloat64 - var bestRemainder []int = nil - var bestCombo []int = nil - acc.iterateCombinations(numas, k, func(combo []int) LoopControl { - // If we've already found a combo with a balance of 0 in a - // different iteration, then don't bother checking any others. - if bestBalance == 0 { - return Break - } - - // Check that this combination of NUMA nodes has enough CPUs to - // satisfy the allocation overall. - cpus := acc.details.CPUsInNUMANodes(combo...) - if cpus.Size() < numCPUs { - return Continue - } - - // Check that CPUs can be handed out in groups of size - // 'cpuGroupSize' across the NUMA nodes in this combo. - numCPUGroups := 0 - for _, numa := range combo { - numCPUGroups += (acc.details.CPUsInNUMANodes(numa).Size() / cpuGroupSize) - } - if (numCPUGroups * cpuGroupSize) < numCPUs { - return Continue - } - - // Check that each NUMA node in this combination can allocate an - // even distribution of CPUs in groups of size 'cpuGroupSize', - // modulo some remainder. - distribution := (numCPUs / len(combo) / cpuGroupSize) * cpuGroupSize - for _, numa := range combo { - cpus := acc.details.CPUsInNUMANodes(numa) - if cpus.Size() < distribution { - return Continue - } - } - - // Calculate how many CPUs will be available on each NUMA node in - // the system after allocating an even distribution of CPU groups - // of size 'cpuGroupSize' from each NUMA node in 'combo'. This will - // be used in the "balance score" calculation to help decide if - // this combo should ultimately be chosen. - availableAfterAllocation := make(mapIntInt, len(numas)) - for _, numa := range numas { - availableAfterAllocation[numa] = acc.details.CPUsInNUMANodes(numa).Size() - } - for _, numa := range combo { - availableAfterAllocation[numa] -= distribution - } - - // Check if there are any remaining CPUs to distribute across the - // NUMA nodes once CPUs have been evenly distributed in groups of - // size 'cpuGroupSize'. - remainder := numCPUs - (distribution * len(combo)) - - // Get a list of NUMA nodes to consider pulling the remainder CPUs - // from. This list excludes NUMA nodes that don't have at least - // 'cpuGroupSize' CPUs available after being allocated - // 'distribution' number of CPUs. - var remainderCombo []int - for _, numa := range combo { - if availableAfterAllocation[numa] >= cpuGroupSize { - remainderCombo = append(remainderCombo, numa) - } - } - - // Declare a set of local variables to help track the "balance - // scores" calculated when using different subsets of - // 'remainderCombo' to allocate remainder CPUs from. - var bestLocalBalance float64 = math.MaxFloat64 - var bestLocalRemainder []int = nil - - // If there aren't any remainder CPUs to allocate, then calculate - // the "balance score" of this combo as the standard deviation of - // the values contained in 'availableAfterAllocation'. - if remainder == 0 { - bestLocalBalance = standardDeviation(availableAfterAllocation.Values()) - bestLocalRemainder = nil - } - - // Otherwise, find the best "balance score" when allocating the - // remainder CPUs across different subsets of NUMA nodes in 'remainderCombo'. - // These remainder CPUs are handed out in groups of size 'cpuGroupSize'. - // We start from k=len(remainderCombo) and walk down to k=1 so that - // we continue to distribute CPUs as much as possible across - // multiple NUMA nodes. - for k := len(remainderCombo); remainder > 0 && k >= 1; k-- { - acc.iterateCombinations(remainderCombo, k, func(subset []int) LoopControl { - // Make a local copy of 'remainder'. - remainder := remainder - - // Make a local copy of 'availableAfterAllocation'. - availableAfterAllocation := availableAfterAllocation.Clone() - - // If this subset is not capable of allocating all - // remainder CPUs, continue to the next one. - if sum(availableAfterAllocation.Values(subset...)) < remainder { - return Continue - } - - // For all NUMA nodes in 'subset', walk through them, - // removing 'cpuGroupSize' number of CPUs from each - // until all remainder CPUs have been accounted for. - for remainder > 0 { - for _, numa := range subset { - if remainder == 0 { - break - } - if availableAfterAllocation[numa] < cpuGroupSize { - continue - } - availableAfterAllocation[numa] -= cpuGroupSize - remainder -= cpuGroupSize - } - } - - // Calculate the "balance score" as the standard deviation - // of the number of CPUs available on all NUMA nodes in the - // system after the remainder CPUs have been allocated - // across 'subset' in groups of size 'cpuGroupSize'. - balance := standardDeviation(availableAfterAllocation.Values()) - if balance < bestLocalBalance { - bestLocalBalance = balance - bestLocalRemainder = subset - } - - return Continue - }) - } - - // If the best "balance score" for this combo is less than the - // lowest "balance score" of all previous combos, then update this - // combo (and remainder set) to be the best one found so far. - if bestLocalBalance < bestBalance { - bestBalance = bestLocalBalance - bestRemainder = bestLocalRemainder - bestCombo = combo - } - - return Continue - }) - - // If we made it through all of the iterations above without finding a - // combination of NUMA nodes that can properly balance CPU allocations, - // then move on to the next larger set of NUMA node combinations. - if bestCombo == nil { - continue - } - - // Otherwise, start allocating CPUs from the NUMA node combination - // chosen. First allocate an even distribution of CPUs in groups of - // size 'cpuGroupSize' from 'bestCombo'. - distribution := (numCPUs / len(bestCombo) / cpuGroupSize) * cpuGroupSize - for _, numa := range bestCombo { - cpus, _ := takeByTopologyNUMAPacked(acc.topo, acc.details.CPUsInNUMANodes(numa), distribution, cpuSortingStrategy, false) - acc.take(cpus) - } - - // Then allocate any remaining CPUs in groups of size 'cpuGroupSize' - // from each NUMA node in the remainder set. - remainder := numCPUs - (distribution * len(bestCombo)) - for remainder > 0 { - for _, numa := range bestRemainder { - if remainder == 0 { - break - } - if acc.details.CPUsInNUMANodes(numa).Size() < cpuGroupSize { - continue - } - cpus, _ := takeByTopologyNUMAPacked(acc.topo, acc.details.CPUsInNUMANodes(numa), cpuGroupSize, cpuSortingStrategy, false) - acc.take(cpus) - remainder -= cpuGroupSize - } - } - - // If we haven't allocated all of our CPUs at this point, then something - // went wrong in our accounting and we should error out. - if acc.numCPUsNeeded > 0 { - return cpuset.New(), fmt.Errorf("accounting error, not enough CPUs allocated, remaining: %v", acc.numCPUsNeeded) - } - - // Likewise, if we have allocated too many CPUs at this point, then something - // went wrong in our accounting and we should error out. - if acc.numCPUsNeeded < 0 { - return cpuset.New(), fmt.Errorf("accounting error, too many CPUs allocated, remaining: %v", acc.numCPUsNeeded) - } - - // Otherwise, return the result - return acc.result, nil - } - - // If we never found a combination of NUMA nodes that we could properly - // distribute CPUs across, fall back to the packing algorithm. - return takeByTopologyNUMAPacked(topo, availableCPUs, numCPUs, cpuSortingStrategy, false) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go deleted file mode 100644 index 8b59ba671..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager.go +++ /dev/null @@ -1,527 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "context" - "fmt" - "math" - "sync" - "time" - - cadvisorapi "github.com/google/cadvisor/info/v1" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/wait" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/klog/v2" - - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/config" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/status" - "k8s.io/utils/cpuset" -) - -// ActivePodsFunc is a function that returns a list of pods to reconcile. -type ActivePodsFunc func() []*v1.Pod - -type runtimeService interface { - UpdateContainerResources(ctx context.Context, id string, resources *runtimeapi.ContainerResources) error -} - -type policyName string - -// cpuManagerStateFileName is the file name where cpu manager stores its state -const cpuManagerStateFileName = "cpu_manager_state" - -// Manager interface provides methods for Kubelet to manage pod cpus. -type Manager interface { - // Start is called during Kubelet initialization. - Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, podStatusProvider status.PodStatusProvider, containerRuntime runtimeService, initialContainers containermap.ContainerMap) error - - // Called to trigger the allocation of CPUs to a container. This must be - // called at some point prior to the AddContainer() call for a container, - // e.g. at pod admission time. - Allocate(pod *v1.Pod, container *v1.Container) error - - // AddContainer adds the mapping between container ID to pod UID and the container name - // The mapping used to remove the CPU allocation during the container removal - AddContainer(p *v1.Pod, c *v1.Container, containerID string) - - // RemoveContainer is called after Kubelet decides to kill or delete a - // container. After this call, the CPU manager stops trying to reconcile - // that container and any CPUs dedicated to the container are freed. - RemoveContainer(containerID string) error - - // State returns a read-only interface to the internal CPU manager state. - State() state.Reader - - // GetTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment among this - // and other resource controllers. - GetTopologyHints(*v1.Pod, *v1.Container) map[string][]topologymanager.TopologyHint - - // GetExclusiveCPUs implements the podresources.CPUsProvider interface to provide - // exclusively allocated cpus for the container - GetExclusiveCPUs(podUID, containerName string) cpuset.CPUSet - - // GetPodTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment per Pod - // among this and other resource controllers. - GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint - - // GetAllocatableCPUs returns the total set of CPUs available for allocation. - GetAllocatableCPUs() cpuset.CPUSet - - // GetCPUAffinity returns cpuset which includes cpus from shared pools - // as well as exclusively allocated cpus - GetCPUAffinity(podUID, containerName string) cpuset.CPUSet - - // GetAllCPUs returns all the CPUs known by cpumanager, as reported by the - // hardware discovery. Maps to the CPU capacity. - GetAllCPUs() cpuset.CPUSet -} - -type manager struct { - sync.Mutex - policy Policy - - // reconcilePeriod is the duration between calls to reconcileState. - reconcilePeriod time.Duration - - // state allows pluggable CPU assignment policies while sharing a common - // representation of state for the system to inspect and reconcile. - state state.State - - // lastUpdatedstate holds state for each container from the last time it was updated. - lastUpdateState state.State - - // containerRuntime is the container runtime service interface needed - // to make UpdateContainerResources() calls against the containers. - containerRuntime runtimeService - - // activePods is a method for listing active pods on the node - // so all the containers can be updated in the reconciliation loop. - activePods ActivePodsFunc - - // podStatusProvider provides a method for obtaining pod statuses - // and the containerID of their containers - podStatusProvider status.PodStatusProvider - - // containerMap provides a mapping from (pod, container) -> containerID - // for all containers a pod - containerMap containermap.ContainerMap - - topology *topology.CPUTopology - - nodeAllocatableReservation v1.ResourceList - - // sourcesReady provides the readiness of kubelet configuration sources such as apiserver update readiness. - // We use it to determine when we can purge inactive pods from checkpointed state. - sourcesReady config.SourcesReady - - // stateFileDirectory holds the directory where the state file for checkpoints is held. - stateFileDirectory string - - // allCPUs is the set of online CPUs as reported by the system - allCPUs cpuset.CPUSet - - // allocatableCPUs is the set of online CPUs as reported by the system, - // and available for allocation, minus the reserved set - allocatableCPUs cpuset.CPUSet -} - -var _ Manager = &manager{} - -type sourcesReadyStub struct{} - -func (s *sourcesReadyStub) AddSource(source string) {} -func (s *sourcesReadyStub) AllReady() bool { return true } - -// NewManager creates new cpu manager based on provided policy -func NewManager(cpuPolicyName string, cpuPolicyOptions map[string]string, reconcilePeriod time.Duration, machineInfo *cadvisorapi.MachineInfo, specificCPUs cpuset.CPUSet, nodeAllocatableReservation v1.ResourceList, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) { - var topo *topology.CPUTopology - var policy Policy - var err error - - topo, err = topology.Discover(machineInfo) - if err != nil { - return nil, err - } - - switch policyName(cpuPolicyName) { - - case PolicyNone: - policy, err = NewNonePolicy(cpuPolicyOptions) - if err != nil { - return nil, fmt.Errorf("new none policy error: %w", err) - } - - case PolicyStatic: - klog.InfoS("Detected CPU topology", "topology", topo) - - reservedCPUs, ok := nodeAllocatableReservation[v1.ResourceCPU] - if !ok { - // The static policy cannot initialize without this information. - return nil, fmt.Errorf("[cpumanager] unable to determine reserved CPU resources for static policy") - } - if reservedCPUs.IsZero() { - // The static policy requires this to be nonzero. Zero CPU reservation - // would allow the shared pool to be completely exhausted. At that point - // either we would violate our guarantee of exclusivity or need to evict - // any pod that has at least one container that requires zero CPUs. - // See the comments in policy_static.go for more details. - return nil, fmt.Errorf("[cpumanager] the static policy requires systemreserved.cpu + kubereserved.cpu to be greater than zero") - } - - // Take the ceiling of the reservation, since fractional CPUs cannot be - // exclusively allocated. - reservedCPUsFloat := float64(reservedCPUs.MilliValue()) / 1000 - numReservedCPUs := int(math.Ceil(reservedCPUsFloat)) - policy, err = NewStaticPolicy(topo, numReservedCPUs, specificCPUs, affinity, cpuPolicyOptions) - if err != nil { - return nil, fmt.Errorf("new static policy error: %w", err) - } - - default: - return nil, fmt.Errorf("unknown policy: \"%s\"", cpuPolicyName) - } - - manager := &manager{ - policy: policy, - reconcilePeriod: reconcilePeriod, - lastUpdateState: state.NewMemoryState(), - topology: topo, - nodeAllocatableReservation: nodeAllocatableReservation, - stateFileDirectory: stateFileDirectory, - allCPUs: topo.CPUDetails.CPUs(), - } - manager.sourcesReady = &sourcesReadyStub{} - return manager, nil -} - -func (m *manager) Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, podStatusProvider status.PodStatusProvider, containerRuntime runtimeService, initialContainers containermap.ContainerMap) error { - klog.InfoS("Starting CPU manager", "policy", m.policy.Name()) - klog.InfoS("Reconciling", "reconcilePeriod", m.reconcilePeriod) - m.sourcesReady = sourcesReady - m.activePods = activePods - m.podStatusProvider = podStatusProvider - m.containerRuntime = containerRuntime - m.containerMap = initialContainers - - stateImpl, err := state.NewCheckpointState(m.stateFileDirectory, cpuManagerStateFileName, m.policy.Name(), m.containerMap) - if err != nil { - klog.ErrorS(err, "Could not initialize checkpoint manager, please drain node and remove policy state file") - return err - } - m.state = stateImpl - - err = m.policy.Start(m.state) - if err != nil { - klog.ErrorS(err, "Policy start error") - return err - } - - klog.V(4).InfoS("CPU manager started", "policy", m.policy.Name()) - - m.allocatableCPUs = m.policy.GetAllocatableCPUs(m.state) - - if m.policy.Name() == string(PolicyNone) { - return nil - } - // Periodically call m.reconcileState() to continue to keep the CPU sets of - // all pods in sync with and guaranteed CPUs handed out among them. - go wait.Until(func() { m.reconcileState() }, m.reconcilePeriod, wait.NeverStop) - return nil -} - -func (m *manager) Allocate(p *v1.Pod, c *v1.Container) error { - // Garbage collect any stranded resources before allocating CPUs. - m.removeStaleState() - - m.Lock() - defer m.Unlock() - - // Call down into the policy to assign this container CPUs if required. - err := m.policy.Allocate(m.state, p, c) - if err != nil { - klog.ErrorS(err, "Allocate error") - return err - } - - return nil -} - -func (m *manager) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) { - m.Lock() - defer m.Unlock() - if cset, exists := m.state.GetCPUSet(string(pod.UID), container.Name); exists { - m.lastUpdateState.SetCPUSet(string(pod.UID), container.Name, cset) - } - m.containerMap.Add(string(pod.UID), container.Name, containerID) -} - -func (m *manager) RemoveContainer(containerID string) error { - m.Lock() - defer m.Unlock() - - err := m.policyRemoveContainerByID(containerID) - if err != nil { - klog.ErrorS(err, "RemoveContainer error") - return err - } - - return nil -} - -func (m *manager) policyRemoveContainerByID(containerID string) error { - podUID, containerName, err := m.containerMap.GetContainerRef(containerID) - if err != nil { - return nil - } - - err = m.policy.RemoveContainer(m.state, podUID, containerName) - if err == nil { - m.lastUpdateState.Delete(podUID, containerName) - m.containerMap.RemoveByContainerID(containerID) - } - - return err -} - -func (m *manager) policyRemoveContainerByRef(podUID string, containerName string) error { - err := m.policy.RemoveContainer(m.state, podUID, containerName) - if err == nil { - m.lastUpdateState.Delete(podUID, containerName) - m.containerMap.RemoveByContainerRef(podUID, containerName) - } - - return err -} - -func (m *manager) State() state.Reader { - return m.state -} - -func (m *manager) GetTopologyHints(pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - // Garbage collect any stranded resources before providing TopologyHints - m.removeStaleState() - // Delegate to active policy - return m.policy.GetTopologyHints(m.state, pod, container) -} - -func (m *manager) GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint { - // Garbage collect any stranded resources before providing TopologyHints - m.removeStaleState() - // Delegate to active policy - return m.policy.GetPodTopologyHints(m.state, pod) -} - -func (m *manager) GetAllocatableCPUs() cpuset.CPUSet { - return m.allocatableCPUs.Clone() -} - -func (m *manager) GetAllCPUs() cpuset.CPUSet { - return m.allCPUs.Clone() -} - -type reconciledContainer struct { - podName string - containerName string - containerID string -} - -func (m *manager) removeStaleState() { - // Only once all sources are ready do we attempt to remove any stale state. - // This ensures that the call to `m.activePods()` below will succeed with - // the actual active pods list. - if !m.sourcesReady.AllReady() { - return - } - - // We grab the lock to ensure that no new containers will grab CPUs while - // executing the code below. Without this lock, its possible that we end up - // removing state that is newly added by an asynchronous call to - // AddContainer() during the execution of this code. - m.Lock() - defer m.Unlock() - - // Get the list of active pods. - activePods := m.activePods() - - // Build a list of (podUID, containerName) pairs for all containers in all active Pods. - activeContainers := make(map[string]map[string]struct{}) - for _, pod := range activePods { - activeContainers[string(pod.UID)] = make(map[string]struct{}) - for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { - activeContainers[string(pod.UID)][container.Name] = struct{}{} - } - } - - // Loop through the CPUManager state. Remove any state for containers not - // in the `activeContainers` list built above. - assignments := m.state.GetCPUAssignments() - for podUID := range assignments { - for containerName := range assignments[podUID] { - if _, ok := activeContainers[podUID][containerName]; ok { - klog.V(5).InfoS("RemoveStaleState: container still active", "podUID", podUID, "containerName", containerName) - continue - } - klog.V(2).InfoS("RemoveStaleState: removing container", "podUID", podUID, "containerName", containerName) - err := m.policyRemoveContainerByRef(podUID, containerName) - if err != nil { - klog.ErrorS(err, "RemoveStaleState: failed to remove container", "podUID", podUID, "containerName", containerName) - } - } - } - - m.containerMap.Visit(func(podUID, containerName, containerID string) { - if _, ok := activeContainers[podUID][containerName]; ok { - klog.V(5).InfoS("RemoveStaleState: containerMap: container still active", "podUID", podUID, "containerName", containerName) - return - } - klog.V(2).InfoS("RemoveStaleState: containerMap: removing container", "podUID", podUID, "containerName", containerName) - err := m.policyRemoveContainerByRef(podUID, containerName) - if err != nil { - klog.ErrorS(err, "RemoveStaleState: containerMap: failed to remove container", "podUID", podUID, "containerName", containerName) - } - }) -} - -func (m *manager) reconcileState() (success []reconciledContainer, failure []reconciledContainer) { - ctx := context.Background() - success = []reconciledContainer{} - failure = []reconciledContainer{} - - m.removeStaleState() - for _, pod := range m.activePods() { - pstatus, ok := m.podStatusProvider.GetPodStatus(pod.UID) - if !ok { - klog.V(5).InfoS("ReconcileState: skipping pod; status not found", "pod", klog.KObj(pod)) - failure = append(failure, reconciledContainer{pod.Name, "", ""}) - continue - } - - allContainers := pod.Spec.InitContainers - allContainers = append(allContainers, pod.Spec.Containers...) - for _, container := range allContainers { - containerID, err := findContainerIDByName(&pstatus, container.Name) - if err != nil { - klog.V(5).InfoS("ReconcileState: skipping container; ID not found in pod status", "pod", klog.KObj(pod), "containerName", container.Name, "err", err) - failure = append(failure, reconciledContainer{pod.Name, container.Name, ""}) - continue - } - - cstatus, err := findContainerStatusByName(&pstatus, container.Name) - if err != nil { - klog.V(5).InfoS("ReconcileState: skipping container; container status not found in pod status", "pod", klog.KObj(pod), "containerName", container.Name, "err", err) - failure = append(failure, reconciledContainer{pod.Name, container.Name, ""}) - continue - } - - if cstatus.State.Waiting != nil || - (cstatus.State.Waiting == nil && cstatus.State.Running == nil && cstatus.State.Terminated == nil) { - klog.V(4).InfoS("ReconcileState: skipping container; container still in the waiting state", "pod", klog.KObj(pod), "containerName", container.Name, "err", err) - failure = append(failure, reconciledContainer{pod.Name, container.Name, ""}) - continue - } - - m.Lock() - if cstatus.State.Terminated != nil { - // The container is terminated but we can't call m.RemoveContainer() - // here because it could remove the allocated cpuset for the container - // which may be in the process of being restarted. That would result - // in the container losing any exclusively-allocated CPUs that it - // was allocated. - _, _, err := m.containerMap.GetContainerRef(containerID) - if err == nil { - klog.V(4).InfoS("ReconcileState: ignoring terminated container", "pod", klog.KObj(pod), "containerID", containerID) - } - m.Unlock() - continue - } - - // Once we make it here we know we have a running container. - // Idempotently add it to the containerMap incase it is missing. - // This can happen after a kubelet restart, for example. - m.containerMap.Add(string(pod.UID), container.Name, containerID) - m.Unlock() - - cset := m.state.GetCPUSetOrDefault(string(pod.UID), container.Name) - if cset.IsEmpty() { - // NOTE: This should not happen outside of tests. - klog.V(2).InfoS("ReconcileState: skipping container; empty cpuset assigned", "pod", klog.KObj(pod), "containerName", container.Name) - failure = append(failure, reconciledContainer{pod.Name, container.Name, containerID}) - continue - } - - lcset := m.lastUpdateState.GetCPUSetOrDefault(string(pod.UID), container.Name) - if !cset.Equals(lcset) { - klog.V(5).InfoS("ReconcileState: updating container", "pod", klog.KObj(pod), "containerName", container.Name, "containerID", containerID, "cpuSet", cset) - err = m.updateContainerCPUSet(ctx, containerID, cset) - if err != nil { - klog.ErrorS(err, "ReconcileState: failed to update container", "pod", klog.KObj(pod), "containerName", container.Name, "containerID", containerID, "cpuSet", cset) - failure = append(failure, reconciledContainer{pod.Name, container.Name, containerID}) - continue - } - m.lastUpdateState.SetCPUSet(string(pod.UID), container.Name, cset) - } - success = append(success, reconciledContainer{pod.Name, container.Name, containerID}) - } - } - return success, failure -} - -func findContainerIDByName(status *v1.PodStatus, name string) (string, error) { - allStatuses := status.InitContainerStatuses - allStatuses = append(allStatuses, status.ContainerStatuses...) - for _, container := range allStatuses { - if container.Name == name && container.ContainerID != "" { - cid := &kubecontainer.ContainerID{} - err := cid.ParseString(container.ContainerID) - if err != nil { - return "", err - } - return cid.ID, nil - } - } - return "", fmt.Errorf("unable to find ID for container with name %v in pod status (it may not be running)", name) -} - -func findContainerStatusByName(status *v1.PodStatus, name string) (*v1.ContainerStatus, error) { - for _, containerStatus := range append(status.InitContainerStatuses, status.ContainerStatuses...) { - if containerStatus.Name == name { - return &containerStatus, nil - } - } - return nil, fmt.Errorf("unable to find status for container with name %v in pod status (it may not be running)", name) -} - -func (m *manager) GetExclusiveCPUs(podUID, containerName string) cpuset.CPUSet { - if result, ok := m.state.GetCPUSet(podUID, containerName); ok { - return result - } - - return cpuset.CPUSet{} -} - -func (m *manager) GetCPUAffinity(podUID, containerName string) cpuset.CPUSet { - return m.state.GetCPUSetOrDefault(podUID, containerName) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go deleted file mode 100644 index 556583b1a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_others.go +++ /dev/null @@ -1,43 +0,0 @@ -//go:build !windows -// +build !windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "context" - - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/utils/cpuset" -) - -func (m *manager) updateContainerCPUSet(ctx context.Context, containerID string, cpus cpuset.CPUSet) error { - // TODO: Consider adding a `ResourceConfigForContainer` helper in - // helpers_linux.go similar to what exists for pods. - // It would be better to pass the full container resources here instead of - // this patch-like partial resources. - - return m.containerRuntime.UpdateContainerResources( - ctx, - containerID, - &runtimeapi.ContainerResources{ - Linux: &runtimeapi.LinuxContainerResources{ - CpusetCpus: cpus.String(), - }, - }) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go deleted file mode 100644 index f9a239ce5..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/cpu_manager_windows.go +++ /dev/null @@ -1,49 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "context" - utilfeature "k8s.io/apiserver/pkg/util/feature" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - kubefeatures "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/winstats" - "k8s.io/utils/cpuset" -) - -func (m *manager) updateContainerCPUSet(ctx context.Context, containerID string, cpus cpuset.CPUSet) error { - if !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.WindowsCPUAndMemoryAffinity) { - return nil - } - - affinities := winstats.CpusToGroupAffinity(cpus.List()) - var cpuGroupAffinities []*runtimeapi.WindowsCpuGroupAffinity - for _, affinity := range affinities { - cpuGroupAffinities = append(cpuGroupAffinities, &runtimeapi.WindowsCpuGroupAffinity{ - CpuGroup: uint32(affinity.Group), - CpuMask: uint64(affinity.Mask), - }) - } - return m.containerRuntime.UpdateContainerResources(ctx, containerID, &runtimeapi.ContainerResources{ - Windows: &runtimeapi.WindowsContainerResources{ - AffinityCpus: cpuGroupAffinities, - }, - }) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go deleted file mode 100644 index 8f00ec378..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/fake_cpu_manager.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/config" - "k8s.io/kubernetes/pkg/kubelet/status" - "k8s.io/utils/cpuset" -) - -type fakeManager struct { - state state.State -} - -func (m *fakeManager) Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, podStatusProvider status.PodStatusProvider, containerRuntime runtimeService, initialContainers containermap.ContainerMap) error { - klog.InfoS("Start()") - return nil -} - -func (m *fakeManager) Policy() Policy { - klog.InfoS("Policy()") - pol, _ := NewNonePolicy(nil) - return pol -} - -func (m *fakeManager) Allocate(pod *v1.Pod, container *v1.Container) error { - klog.InfoS("Allocate", "pod", klog.KObj(pod), "containerName", container.Name) - return nil -} - -func (m *fakeManager) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) { - klog.InfoS("AddContainer", "pod", klog.KObj(pod), "containerName", container.Name, "containerID", containerID) -} - -func (m *fakeManager) RemoveContainer(containerID string) error { - klog.InfoS("RemoveContainer", "containerID", containerID) - return nil -} - -func (m *fakeManager) GetTopologyHints(pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - klog.InfoS("Get container topology hints") - return map[string][]topologymanager.TopologyHint{} -} - -func (m *fakeManager) GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint { - klog.InfoS("Get pod topology hints") - return map[string][]topologymanager.TopologyHint{} -} - -func (m *fakeManager) State() state.Reader { - return m.state -} - -func (m *fakeManager) GetExclusiveCPUs(podUID, containerName string) cpuset.CPUSet { - klog.InfoS("GetExclusiveCPUs", "podUID", podUID, "containerName", containerName) - return cpuset.CPUSet{} -} - -func (m *fakeManager) GetAllocatableCPUs() cpuset.CPUSet { - klog.InfoS("Get Allocatable CPUs") - return cpuset.CPUSet{} -} - -func (m *fakeManager) GetCPUAffinity(podUID, containerName string) cpuset.CPUSet { - klog.InfoS("GetCPUAffinity", "podUID", podUID, "containerName", containerName) - return cpuset.CPUSet{} -} - -func (m *fakeManager) GetAllCPUs() cpuset.CPUSet { - klog.InfoS("GetAllCPUs") - return cpuset.CPUSet{} -} - -// NewFakeManager creates empty/fake cpu manager -func NewFakeManager() Manager { - return &fakeManager{ - state: state.NewMemoryState(), - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go deleted file mode 100644 index a80da9427..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "k8s.io/api/core/v1" - - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/utils/cpuset" -) - -// Policy implements logic for pod container to CPU assignment. -type Policy interface { - Name() string - Start(s state.State) error - // Allocate call is idempotent - Allocate(s state.State, pod *v1.Pod, container *v1.Container) error - // RemoveContainer call is idempotent - RemoveContainer(s state.State, podUID string, containerName string) error - // GetTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment among this - // and other resource controllers. - GetTopologyHints(s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint - // GetPodTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment per Pod - // among this and other resource controllers. - GetPodTopologyHints(s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint - // GetAllocatableCPUs returns the total set of CPUs available for allocation. - GetAllocatableCPUs(m state.State) cpuset.CPUSet -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go deleted file mode 100644 index ff86498fd..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_none.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "fmt" - - "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/utils/cpuset" -) - -type nonePolicy struct{} - -var _ Policy = &nonePolicy{} - -// PolicyNone name of none policy -const PolicyNone policyName = "none" - -// NewNonePolicy returns a cpuset manager policy that does nothing -func NewNonePolicy(cpuPolicyOptions map[string]string) (Policy, error) { - if len(cpuPolicyOptions) > 0 { - return nil, fmt.Errorf("None policy: received unsupported options=%v", cpuPolicyOptions) - } - return &nonePolicy{}, nil -} - -func (p *nonePolicy) Name() string { - return string(PolicyNone) -} - -func (p *nonePolicy) Start(s state.State) error { - klog.InfoS("None policy: Start") - return nil -} - -func (p *nonePolicy) Allocate(s state.State, pod *v1.Pod, container *v1.Container) error { - return nil -} - -func (p *nonePolicy) RemoveContainer(s state.State, podUID string, containerName string) error { - return nil -} - -func (p *nonePolicy) GetTopologyHints(s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - return nil -} - -func (p *nonePolicy) GetPodTopologyHints(s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint { - return nil -} - -// Assignable CPUs are the ones that can be exclusively allocated to pods that meet the exclusivity requirement -// (ie guaranteed QoS class and integral CPU request). -// Assignability of CPUs as a concept is only applicable in case of static policy i.e. scenarios where workloads -// CAN get exclusive access to core(s). -// Hence, we return empty set here: no cpus are assignable according to above definition with this policy. -func (p *nonePolicy) GetAllocatableCPUs(m state.State) cpuset.CPUSet { - return cpuset.New() -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go deleted file mode 100644 index 65b415bda..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_options.go +++ /dev/null @@ -1,187 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "fmt" - "strconv" - - "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" - kubefeatures "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" -) - -// Names of the options, as part of the user interface. -const ( - FullPCPUsOnlyOption string = "full-pcpus-only" - DistributeCPUsAcrossNUMAOption string = "distribute-cpus-across-numa" - AlignBySocketOption string = "align-by-socket" - DistributeCPUsAcrossCoresOption string = "distribute-cpus-across-cores" - StrictCPUReservationOption string = "strict-cpu-reservation" - PreferAlignByUnCoreCacheOption string = "prefer-align-cpus-by-uncorecache" -) - -var ( - alphaOptions = sets.New[string]( - AlignBySocketOption, - DistributeCPUsAcrossCoresOption, - PreferAlignByUnCoreCacheOption, - ) - betaOptions = sets.New[string]( - StrictCPUReservationOption, - DistributeCPUsAcrossNUMAOption, - ) - stableOptions = sets.New[string]( - FullPCPUsOnlyOption, - ) -) - -// CheckPolicyOptionAvailable verifies if the given option can be used depending on the Feature Gate Settings. -// returns nil on success, or an error describing the failure on error. -func CheckPolicyOptionAvailable(option string) error { - if !alphaOptions.Has(option) && !betaOptions.Has(option) && !stableOptions.Has(option) { - return fmt.Errorf("unknown CPU Manager Policy option: %q", option) - } - - if alphaOptions.Has(option) && !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManagerPolicyAlphaOptions) { - return fmt.Errorf("CPU Manager Policy Alpha-level Options not enabled, but option %q provided", option) - } - - if betaOptions.Has(option) && !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUManagerPolicyBetaOptions) { - return fmt.Errorf("CPU Manager Policy Beta-level Options not enabled, but option %q provided", option) - } - - // if the option is stable, we need no CPUManagerPolicy*Options feature gate check - return nil -} - -// StaticPolicyOptions holds the parsed value of the policy options, ready to be consumed internally. -type StaticPolicyOptions struct { - // flag to enable extra allocation restrictions to avoid - // different containers to possibly end up on the same core. - // we consider "core" and "physical CPU" synonim here, leaning - // towards the terminoloy k8s hints. We acknowledge this is confusing. - // - // looking at https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/, - // any possible naming scheme will lead to ambiguity to some extent. - // We picked "pcpu" because it the established docs hints at vCPU already. - FullPhysicalCPUsOnly bool - // Flag to evenly distribute CPUs across NUMA nodes in cases where more - // than one NUMA node is required to satisfy the allocation. - DistributeCPUsAcrossNUMA bool - // Flag to ensure CPUs are considered aligned at socket boundary rather than - // NUMA boundary - AlignBySocket bool - // flag to enable extra allocation restrictions to spread - // cpus (HT) on different physical core. - // This is a preferred policy so do not throw error if they have to packed in one physical core. - DistributeCPUsAcrossCores bool - // Flag to remove reserved cores from the list of available cores - StrictCPUReservation bool - // Flag that makes best-effort to align CPUs to a uncorecache boundary - // As long as there are CPUs available, pods will be admitted if the condition is not met. - PreferAlignByUncoreCacheOption bool -} - -// NewStaticPolicyOptions creates a StaticPolicyOptions struct from the user configuration. -func NewStaticPolicyOptions(policyOptions map[string]string) (StaticPolicyOptions, error) { - opts := StaticPolicyOptions{} - for name, value := range policyOptions { - if err := CheckPolicyOptionAvailable(name); err != nil { - return opts, err - } - - switch name { - case FullPCPUsOnlyOption: - optValue, err := strconv.ParseBool(value) - if err != nil { - return opts, fmt.Errorf("bad value for option %q: %w", name, err) - } - opts.FullPhysicalCPUsOnly = optValue - case DistributeCPUsAcrossNUMAOption: - optValue, err := strconv.ParseBool(value) - if err != nil { - return opts, fmt.Errorf("bad value for option %q: %w", name, err) - } - opts.DistributeCPUsAcrossNUMA = optValue - case AlignBySocketOption: - optValue, err := strconv.ParseBool(value) - if err != nil { - return opts, fmt.Errorf("bad value for option %q: %w", name, err) - } - opts.AlignBySocket = optValue - case DistributeCPUsAcrossCoresOption: - optValue, err := strconv.ParseBool(value) - if err != nil { - return opts, fmt.Errorf("bad value for option %q: %w", name, err) - } - opts.DistributeCPUsAcrossCores = optValue - case StrictCPUReservationOption: - optValue, err := strconv.ParseBool(value) - if err != nil { - return opts, fmt.Errorf("bad value for option %q: %w", name, err) - } - opts.StrictCPUReservation = optValue - case PreferAlignByUnCoreCacheOption: - optValue, err := strconv.ParseBool(value) - if err != nil { - return opts, fmt.Errorf("bad value for option %q: %w", name, err) - } - opts.PreferAlignByUncoreCacheOption = optValue - default: - // this should never be reached, we already detect unknown options, - // but we keep it as further safety. - return opts, fmt.Errorf("unsupported cpumanager option: %q (%s)", name, value) - } - } - - if opts.FullPhysicalCPUsOnly && opts.DistributeCPUsAcrossCores { - return opts, fmt.Errorf("static policy options %s and %s can not be used at the same time", FullPCPUsOnlyOption, DistributeCPUsAcrossCoresOption) - } - - // TODO(@Jeffwan): Remove this check after more compatibility tests are done. - if opts.DistributeCPUsAcrossNUMA && opts.DistributeCPUsAcrossCores { - return opts, fmt.Errorf("static policy options %s and %s can not be used at the same time", DistributeCPUsAcrossNUMAOption, DistributeCPUsAcrossCoresOption) - } - - if opts.PreferAlignByUncoreCacheOption && opts.DistributeCPUsAcrossCores { - return opts, fmt.Errorf("static policy options %s and %s can not be used at the same time", PreferAlignByUnCoreCacheOption, DistributeCPUsAcrossCoresOption) - } - - if opts.PreferAlignByUncoreCacheOption && opts.DistributeCPUsAcrossNUMA { - return opts, fmt.Errorf("static policy options %s and %s can not be used at the same time", PreferAlignByUnCoreCacheOption, DistributeCPUsAcrossNUMAOption) - } - - return opts, nil -} - -// ValidateStaticPolicyOptions ensures that the requested policy options are compatible with the machine on which the CPUManager is running. -func ValidateStaticPolicyOptions(opts StaticPolicyOptions, topology *topology.CPUTopology, topologyManager topologymanager.Store) error { - if opts.AlignBySocket { - // Not compatible with topology manager single-numa-node policy option. - if topologyManager.GetPolicy().Name() == topologymanager.PolicySingleNumaNode { - return fmt.Errorf("Topolgy manager %s policy is incompatible with CPUManager %s policy option", topologymanager.PolicySingleNumaNode, AlignBySocketOption) - } - // Not compatible with topology when number of sockets are more than number of NUMA nodes. - if topology.NumSockets > topology.NumNUMANodes { - return fmt.Errorf("Align by socket is not compatible with hardware where number of sockets are more than number of NUMA") - } - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go deleted file mode 100644 index 28591c5ba..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/policy_static.go +++ /dev/null @@ -1,816 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cpumanager - -import ( - "fmt" - "strconv" - - v1 "k8s.io/api/core/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" - "k8s.io/kubernetes/pkg/kubelet/metrics" - "k8s.io/utils/cpuset" -) - -const ( - - // PolicyStatic is the name of the static policy. - // Should options be given, these will be ignored and backward (up to 1.21 included) - // compatible behaviour will be enforced - PolicyStatic policyName = "static" - // ErrorSMTAlignment represents the type of an SMTAlignmentError - ErrorSMTAlignment = "SMTAlignmentError" -) - -// SMTAlignmentError represents an error due to SMT alignment -type SMTAlignmentError struct { - RequestedCPUs int - CpusPerCore int - AvailablePhysicalCPUs int - CausedByPhysicalCPUs bool -} - -func (e SMTAlignmentError) Error() string { - if e.CausedByPhysicalCPUs { - return fmt.Sprintf("SMT Alignment Error: not enough free physical CPUs: available physical CPUs = %d, requested CPUs = %d, CPUs per core = %d", e.AvailablePhysicalCPUs, e.RequestedCPUs, e.CpusPerCore) - } - return fmt.Sprintf("SMT Alignment Error: requested %d cpus not multiple cpus per core = %d", e.RequestedCPUs, e.CpusPerCore) -} - -// Type returns human-readable type of this error. Used in the admission control to populate Admission Failure reason. -func (e SMTAlignmentError) Type() string { - return ErrorSMTAlignment -} - -// staticPolicy is a CPU manager policy that does not change CPU -// assignments for exclusively pinned guaranteed containers after the main -// container process starts. -// -// This policy allocates CPUs exclusively for a container if all the following -// conditions are met: -// -// - The pod QoS class is Guaranteed. -// - The CPU request is a positive integer. -// -// The static policy maintains the following sets of logical CPUs: -// -// - SHARED: Burstable, BestEffort, and non-integral Guaranteed containers -// run here. Initially this contains all CPU IDs on the system. As -// exclusive allocations are created and destroyed, this CPU set shrinks -// and grows, accordingly. This is stored in the state as the default -// CPU set. -// -// - RESERVED: A subset of the shared pool which is not exclusively -// allocatable. The membership of this pool is static for the lifetime of -// the Kubelet. The size of the reserved pool is -// ceil(systemreserved.cpu + kubereserved.cpu). -// Reserved CPUs are taken topologically starting with lowest-indexed -// physical core, as reported by cAdvisor. -// -// - ASSIGNABLE: Equal to SHARED - RESERVED. Exclusive CPUs are allocated -// from this pool. -// -// - EXCLUSIVE ALLOCATIONS: CPU sets assigned exclusively to one container. -// These are stored as explicit assignments in the state. -// -// When an exclusive allocation is made, the static policy also updates the -// default cpuset in the state abstraction. The CPU manager's periodic -// reconcile loop takes care of rewriting the cpuset in cgroupfs for any -// containers that may be running in the shared pool. For this reason, -// applications running within exclusively-allocated containers must tolerate -// potentially sharing their allocated CPUs for up to the CPU manager -// reconcile period. -type staticPolicy struct { - // cpu socket topology - topology *topology.CPUTopology - // set of CPUs that is not available for exclusive assignment - reservedCPUs cpuset.CPUSet - // Superset of reservedCPUs. It includes not just the reservedCPUs themselves, - // but also any siblings of those reservedCPUs on the same physical die. - // NOTE: If the reserved set includes full physical CPUs from the beginning - // (e.g. only reserved pairs of core siblings) this set is expected to be - // identical to the reserved set. - reservedPhysicalCPUs cpuset.CPUSet - // topology manager reference to get container Topology affinity - affinity topologymanager.Store - // set of CPUs to reuse across allocations in a pod - cpusToReuse map[string]cpuset.CPUSet - // options allow to fine-tune the behaviour of the policy - options StaticPolicyOptions - // we compute this value multiple time, and it's not supposed to change - // at runtime - the cpumanager can't deal with runtime topology changes anyway. - cpuGroupSize int -} - -// Ensure staticPolicy implements Policy interface -var _ Policy = &staticPolicy{} - -// NewStaticPolicy returns a CPU manager policy that does not change CPU -// assignments for exclusively pinned guaranteed containers after the main -// container process starts. -func NewStaticPolicy(topology *topology.CPUTopology, numReservedCPUs int, reservedCPUs cpuset.CPUSet, affinity topologymanager.Store, cpuPolicyOptions map[string]string) (Policy, error) { - opts, err := NewStaticPolicyOptions(cpuPolicyOptions) - if err != nil { - return nil, err - } - err = ValidateStaticPolicyOptions(opts, topology, affinity) - if err != nil { - return nil, err - } - - cpuGroupSize := topology.CPUsPerCore() - klog.InfoS("Static policy created with configuration", "options", opts, "cpuGroupSize", cpuGroupSize) - - policy := &staticPolicy{ - topology: topology, - affinity: affinity, - cpusToReuse: make(map[string]cpuset.CPUSet), - options: opts, - cpuGroupSize: cpuGroupSize, - } - - allCPUs := topology.CPUDetails.CPUs() - var reserved cpuset.CPUSet - if reservedCPUs.Size() > 0 { - reserved = reservedCPUs - } else { - // takeByTopology allocates CPUs associated with low-numbered cores from - // allCPUs. - // - // For example: Given a system with 8 CPUs available and HT enabled, - // if numReservedCPUs=2, then reserved={0,4} - reserved, _ = policy.takeByTopology(allCPUs, numReservedCPUs) - } - - if reserved.Size() != numReservedCPUs { - err := fmt.Errorf("[cpumanager] unable to reserve the required amount of CPUs (size of %s did not equal %d)", reserved, numReservedCPUs) - return nil, err - } - - var reservedPhysicalCPUs cpuset.CPUSet - for _, cpu := range reserved.UnsortedList() { - core, err := topology.CPUCoreID(cpu) - if err != nil { - return nil, fmt.Errorf("[cpumanager] unable to build the reserved physical CPUs from the reserved set: %w", err) - } - reservedPhysicalCPUs = reservedPhysicalCPUs.Union(topology.CPUDetails.CPUsInCores(core)) - } - - klog.InfoS("Reserved CPUs not available for exclusive assignment", "reservedSize", reserved.Size(), "reserved", reserved, "reservedPhysicalCPUs", reservedPhysicalCPUs) - policy.reservedCPUs = reserved - policy.reservedPhysicalCPUs = reservedPhysicalCPUs - - return policy, nil -} - -func (p *staticPolicy) Name() string { - return string(PolicyStatic) -} - -func (p *staticPolicy) Start(s state.State) error { - if err := p.validateState(s); err != nil { - klog.ErrorS(err, "Static policy invalid state, please drain node and remove policy state file") - return err - } - p.initializeMetrics(s) - return nil -} - -func (p *staticPolicy) validateState(s state.State) error { - tmpAssignments := s.GetCPUAssignments() - tmpDefaultCPUset := s.GetDefaultCPUSet() - - allCPUs := p.topology.CPUDetails.CPUs() - if p.options.StrictCPUReservation { - allCPUs = allCPUs.Difference(p.reservedCPUs) - } - - // Default cpuset cannot be empty when assignments exist - if tmpDefaultCPUset.IsEmpty() { - if len(tmpAssignments) != 0 { - return fmt.Errorf("default cpuset cannot be empty") - } - // state is empty initialize - s.SetDefaultCPUSet(allCPUs) - klog.InfoS("Static policy initialized", "defaultCPUSet", allCPUs) - return nil - } - - // State has already been initialized from file (is not empty) - // 1. Check if the reserved cpuset is not part of default cpuset because: - // - kube/system reserved have changed (increased) - may lead to some containers not being able to start - // - user tampered with file - if p.options.StrictCPUReservation { - if !p.reservedCPUs.Intersection(tmpDefaultCPUset).IsEmpty() { - return fmt.Errorf("some of strictly reserved cpus: \"%s\" are present in defaultCpuSet: \"%s\"", - p.reservedCPUs.Intersection(tmpDefaultCPUset).String(), tmpDefaultCPUset.String()) - } - } else { - if !p.reservedCPUs.Intersection(tmpDefaultCPUset).Equals(p.reservedCPUs) { - return fmt.Errorf("not all reserved cpus: \"%s\" are present in defaultCpuSet: \"%s\"", - p.reservedCPUs.String(), tmpDefaultCPUset.String()) - } - } - - // 2. Check if state for static policy is consistent - for pod := range tmpAssignments { - for container, cset := range tmpAssignments[pod] { - // None of the cpu in DEFAULT cset should be in s.assignments - if !tmpDefaultCPUset.Intersection(cset).IsEmpty() { - return fmt.Errorf("pod: %s, container: %s cpuset: \"%s\" overlaps with default cpuset \"%s\"", - pod, container, cset.String(), tmpDefaultCPUset.String()) - } - } - } - - // 3. It's possible that the set of available CPUs has changed since - // the state was written. This can be due to for example - // offlining a CPU when kubelet is not running. If this happens, - // CPU manager will run into trouble when later it tries to - // assign non-existent CPUs to containers. Validate that the - // topology that was received during CPU manager startup matches with - // the set of CPUs stored in the state. - totalKnownCPUs := tmpDefaultCPUset.Clone() - tmpCPUSets := []cpuset.CPUSet{} - for pod := range tmpAssignments { - for _, cset := range tmpAssignments[pod] { - tmpCPUSets = append(tmpCPUSets, cset) - } - } - totalKnownCPUs = totalKnownCPUs.Union(tmpCPUSets...) - if !totalKnownCPUs.Equals(allCPUs) { - return fmt.Errorf("current set of available CPUs \"%s\" doesn't match with CPUs in state \"%s\"", - allCPUs.String(), totalKnownCPUs.String()) - - } - - return nil -} - -// GetAllocatableCPUs returns the total set of CPUs available for allocation. -func (p *staticPolicy) GetAllocatableCPUs(s state.State) cpuset.CPUSet { - return p.topology.CPUDetails.CPUs().Difference(p.reservedCPUs) -} - -// GetAvailableCPUs returns the set of unassigned CPUs minus the reserved set. -func (p *staticPolicy) GetAvailableCPUs(s state.State) cpuset.CPUSet { - return s.GetDefaultCPUSet().Difference(p.reservedCPUs) -} - -func (p *staticPolicy) GetAvailablePhysicalCPUs(s state.State) cpuset.CPUSet { - return s.GetDefaultCPUSet().Difference(p.reservedPhysicalCPUs) -} - -func (p *staticPolicy) updateCPUsToReuse(pod *v1.Pod, container *v1.Container, cset cpuset.CPUSet) { - // If pod entries to m.cpusToReuse other than the current pod exist, delete them. - for podUID := range p.cpusToReuse { - if podUID != string(pod.UID) { - delete(p.cpusToReuse, podUID) - } - } - // If no cpuset exists for cpusToReuse by this pod yet, create one. - if _, ok := p.cpusToReuse[string(pod.UID)]; !ok { - p.cpusToReuse[string(pod.UID)] = cpuset.New() - } - // Check if the container is an init container. - // If so, add its cpuset to the cpuset of reusable CPUs for any new allocations. - for _, initContainer := range pod.Spec.InitContainers { - if container.Name == initContainer.Name { - if podutil.IsRestartableInitContainer(&initContainer) { - // If the container is a restartable init container, we should not - // reuse its cpuset, as a restartable init container can run with - // regular containers. - break - } - p.cpusToReuse[string(pod.UID)] = p.cpusToReuse[string(pod.UID)].Union(cset) - return - } - } - // Otherwise it is an app container. - // Remove its cpuset from the cpuset of reusable CPUs for any new allocations. - p.cpusToReuse[string(pod.UID)] = p.cpusToReuse[string(pod.UID)].Difference(cset) -} - -func (p *staticPolicy) Allocate(s state.State, pod *v1.Pod, container *v1.Container) (rerr error) { - numCPUs := p.guaranteedCPUs(pod, container) - if numCPUs == 0 { - // container belongs in the shared pool (nothing to do; use default cpuset) - return nil - } - - klog.InfoS("Static policy: Allocate", "pod", klog.KObj(pod), "containerName", container.Name) - // container belongs in an exclusively allocated pool - metrics.CPUManagerPinningRequestsTotal.Inc() - defer func() { - if rerr != nil { - metrics.CPUManagerPinningErrorsTotal.Inc() - if p.options.FullPhysicalCPUsOnly { - metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedPhysicalCPU).Inc() - } - return - } - // TODO: move in updateMetricsOnAllocate - if p.options.FullPhysicalCPUsOnly { - // increment only if we know we allocate aligned resources - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedPhysicalCPU).Inc() - } - }() - - if p.options.FullPhysicalCPUsOnly { - if (numCPUs % p.cpuGroupSize) != 0 { - // Since CPU Manager has been enabled requesting strict SMT alignment, it means a guaranteed pod can only be admitted - // if the CPU requested is a multiple of the number of virtual cpus per physical cores. - // In case CPU request is not a multiple of the number of virtual cpus per physical cores the Pod will be put - // in Failed state, with SMTAlignmentError as reason. Since the allocation happens in terms of physical cores - // and the scheduler is responsible for ensuring that the workload goes to a node that has enough CPUs, - // the pod would be placed on a node where there are enough physical cores available to be allocated. - // Just like the behaviour in case of static policy, takeByTopology will try to first allocate CPUs from the same socket - // and only in case the request cannot be sattisfied on a single socket, CPU allocation is done for a workload to occupy all - // CPUs on a physical core. Allocation of individual threads would never have to occur. - return SMTAlignmentError{ - RequestedCPUs: numCPUs, - CpusPerCore: p.cpuGroupSize, - CausedByPhysicalCPUs: false, - } - } - - availablePhysicalCPUs := p.GetAvailablePhysicalCPUs(s).Size() - - // It's legal to reserve CPUs which are not core siblings. In this case the CPU allocator can descend to single cores - // when picking CPUs. This will void the guarantee of FullPhysicalCPUsOnly. To prevent this, we need to additionally consider - // all the core siblings of the reserved CPUs as unavailable when computing the free CPUs, before to start the actual allocation. - // This way, by construction all possible CPUs allocation whose number is multiple of the SMT level are now correct again. - if numCPUs > availablePhysicalCPUs { - return SMTAlignmentError{ - RequestedCPUs: numCPUs, - CpusPerCore: p.cpuGroupSize, - AvailablePhysicalCPUs: availablePhysicalCPUs, - CausedByPhysicalCPUs: true, - } - } - } - if cset, ok := s.GetCPUSet(string(pod.UID), container.Name); ok { - p.updateCPUsToReuse(pod, container, cset) - klog.InfoS("Static policy: container already present in state, skipping", "pod", klog.KObj(pod), "containerName", container.Name) - return nil - } - - // Call Topology Manager to get the aligned socket affinity across all hint providers. - hint := p.affinity.GetAffinity(string(pod.UID), container.Name) - klog.InfoS("Topology Affinity", "pod", klog.KObj(pod), "containerName", container.Name, "affinity", hint) - - // Allocate CPUs according to the NUMA affinity contained in the hint. - cpuAllocation, err := p.allocateCPUs(s, numCPUs, hint.NUMANodeAffinity, p.cpusToReuse[string(pod.UID)]) - if err != nil { - klog.ErrorS(err, "Unable to allocate CPUs", "pod", klog.KObj(pod), "containerName", container.Name, "numCPUs", numCPUs) - return err - } - - s.SetCPUSet(string(pod.UID), container.Name, cpuAllocation.CPUs) - p.updateCPUsToReuse(pod, container, cpuAllocation.CPUs) - p.updateMetricsOnAllocate(s, cpuAllocation) - - klog.V(4).InfoS("Allocated exclusive CPUs", "pod", klog.KObj(pod), "containerName", container.Name, "cpuset", cpuAllocation.CPUs.String()) - return nil -} - -// getAssignedCPUsOfSiblings returns assigned cpus of given container's siblings(all containers other than the given container) in the given pod `podUID`. -func getAssignedCPUsOfSiblings(s state.State, podUID string, containerName string) cpuset.CPUSet { - assignments := s.GetCPUAssignments() - cset := cpuset.New() - for name, cpus := range assignments[podUID] { - if containerName == name { - continue - } - cset = cset.Union(cpus) - } - return cset -} - -func (p *staticPolicy) RemoveContainer(s state.State, podUID string, containerName string) error { - klog.InfoS("Static policy: RemoveContainer", "podUID", podUID, "containerName", containerName) - cpusInUse := getAssignedCPUsOfSiblings(s, podUID, containerName) - if toRelease, ok := s.GetCPUSet(podUID, containerName); ok { - s.Delete(podUID, containerName) - // Mutate the shared pool, adding released cpus. - toRelease = toRelease.Difference(cpusInUse) - s.SetDefaultCPUSet(s.GetDefaultCPUSet().Union(toRelease)) - p.updateMetricsOnRelease(s, toRelease) - - } - return nil -} - -func (p *staticPolicy) allocateCPUs(s state.State, numCPUs int, numaAffinity bitmask.BitMask, reusableCPUs cpuset.CPUSet) (topology.Allocation, error) { - klog.InfoS("AllocateCPUs", "numCPUs", numCPUs, "socket", numaAffinity) - - allocatableCPUs := p.GetAvailableCPUs(s).Union(reusableCPUs) - - // If there are aligned CPUs in numaAffinity, attempt to take those first. - result := topology.EmptyAllocation() - if numaAffinity != nil { - alignedCPUs := p.getAlignedCPUs(numaAffinity, allocatableCPUs) - - numAlignedToAlloc := alignedCPUs.Size() - if numCPUs < numAlignedToAlloc { - numAlignedToAlloc = numCPUs - } - - allocatedCPUs, err := p.takeByTopology(alignedCPUs, numAlignedToAlloc) - if err != nil { - return topology.EmptyAllocation(), err - } - - result.CPUs = result.CPUs.Union(allocatedCPUs) - } - - // Get any remaining CPUs from what's leftover after attempting to grab aligned ones. - remainingCPUs, err := p.takeByTopology(allocatableCPUs.Difference(result.CPUs), numCPUs-result.CPUs.Size()) - if err != nil { - return topology.EmptyAllocation(), err - } - result.CPUs = result.CPUs.Union(remainingCPUs) - result.Aligned = p.topology.CheckAlignment(result.CPUs) - - // Remove allocated CPUs from the shared CPUSet. - s.SetDefaultCPUSet(s.GetDefaultCPUSet().Difference(result.CPUs)) - - klog.InfoS("AllocateCPUs", "result", result.String()) - return result, nil -} - -func (p *staticPolicy) guaranteedCPUs(pod *v1.Pod, container *v1.Container) int { - qos := v1qos.GetPodQOS(pod) - if qos != v1.PodQOSGuaranteed { - klog.V(5).InfoS("Exclusive CPU allocation skipped, pod QoS is not guaranteed", "pod", klog.KObj(pod), "containerName", container.Name, "qos", qos) - return 0 - } - cpuQuantity := container.Resources.Requests[v1.ResourceCPU] - // In-place pod resize feature makes Container.Resources field mutable for CPU & memory. - // AllocatedResources holds the value of Container.Resources.Requests when the pod was admitted. - // We should return this value because this is what kubelet agreed to allocate for the container - // and the value configured with runtime. - if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { - containerStatuses := pod.Status.ContainerStatuses - if podutil.IsRestartableInitContainer(container) { - if len(pod.Status.InitContainerStatuses) != 0 { - containerStatuses = append(containerStatuses, pod.Status.InitContainerStatuses...) - } - } - if cs, ok := podutil.GetContainerStatus(containerStatuses, container.Name); ok { - cpuQuantity = cs.AllocatedResources[v1.ResourceCPU] - } - } - cpuValue := cpuQuantity.Value() - if cpuValue*1000 != cpuQuantity.MilliValue() { - klog.V(5).InfoS("Exclusive CPU allocation skipped, pod requested non-integral CPUs", "pod", klog.KObj(pod), "containerName", container.Name, "cpu", cpuValue) - return 0 - } - // Safe downcast to do for all systems with < 2.1 billion CPUs. - // Per the language spec, `int` is guaranteed to be at least 32 bits wide. - // https://golang.org/ref/spec#Numeric_types - return int(cpuQuantity.Value()) -} - -func (p *staticPolicy) podGuaranteedCPUs(pod *v1.Pod) int { - // The maximum of requested CPUs by init containers. - requestedByInitContainers := 0 - requestedByRestartableInitContainers := 0 - for _, container := range pod.Spec.InitContainers { - if _, ok := container.Resources.Requests[v1.ResourceCPU]; !ok { - continue - } - requestedCPU := p.guaranteedCPUs(pod, &container) - // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/753-sidecar-containers#resources-calculation-for-scheduling-and-pod-admission - // for the detail. - if podutil.IsRestartableInitContainer(&container) { - requestedByRestartableInitContainers += requestedCPU - } else if requestedByRestartableInitContainers+requestedCPU > requestedByInitContainers { - requestedByInitContainers = requestedByRestartableInitContainers + requestedCPU - } - } - - // The sum of requested CPUs by app containers. - requestedByAppContainers := 0 - for _, container := range pod.Spec.Containers { - if _, ok := container.Resources.Requests[v1.ResourceCPU]; !ok { - continue - } - requestedByAppContainers += p.guaranteedCPUs(pod, &container) - } - - requestedByLongRunningContainers := requestedByAppContainers + requestedByRestartableInitContainers - if requestedByInitContainers > requestedByLongRunningContainers { - return requestedByInitContainers - } - return requestedByLongRunningContainers -} - -func (p *staticPolicy) takeByTopology(availableCPUs cpuset.CPUSet, numCPUs int) (cpuset.CPUSet, error) { - cpuSortingStrategy := CPUSortingStrategyPacked - if p.options.DistributeCPUsAcrossCores { - cpuSortingStrategy = CPUSortingStrategySpread - } - - if p.options.DistributeCPUsAcrossNUMA { - cpuGroupSize := 1 - if p.options.FullPhysicalCPUsOnly { - cpuGroupSize = p.cpuGroupSize - } - return takeByTopologyNUMADistributed(p.topology, availableCPUs, numCPUs, cpuGroupSize, cpuSortingStrategy) - } - - return takeByTopologyNUMAPacked(p.topology, availableCPUs, numCPUs, cpuSortingStrategy, p.options.PreferAlignByUncoreCacheOption) -} - -func (p *staticPolicy) GetTopologyHints(s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - // Get a count of how many guaranteed CPUs have been requested. - requested := p.guaranteedCPUs(pod, container) - - // Number of required CPUs is not an integer or a container is not part of the Guaranteed QoS class. - // It will be treated by the TopologyManager as having no preference and cause it to ignore this - // resource when considering pod alignment. - // In terms of hints, this is equal to: TopologyHints[NUMANodeAffinity: nil, Preferred: true]. - if requested == 0 { - return nil - } - - // Short circuit to regenerate the same hints if there are already - // guaranteed CPUs allocated to the Container. This might happen after a - // kubelet restart, for example. - if allocated, exists := s.GetCPUSet(string(pod.UID), container.Name); exists { - if allocated.Size() != requested { - klog.InfoS("CPUs already allocated to container with different number than request", "pod", klog.KObj(pod), "containerName", container.Name, "requestedSize", requested, "allocatedSize", allocated.Size()) - // An empty list of hints will be treated as a preference that cannot be satisfied. - // In definition of hints this is equal to: TopologyHint[NUMANodeAffinity: nil, Preferred: false]. - // For all but the best-effort policy, the Topology Manager will throw a pod-admission error. - return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): {}, - } - } - klog.InfoS("Regenerating TopologyHints for CPUs already allocated", "pod", klog.KObj(pod), "containerName", container.Name) - return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): p.generateCPUTopologyHints(allocated, cpuset.CPUSet{}, requested), - } - } - - // Get a list of available CPUs. - available := p.GetAvailableCPUs(s) - - // Get a list of reusable CPUs (e.g. CPUs reused from initContainers). - // It should be an empty CPUSet for a newly created pod. - reusable := p.cpusToReuse[string(pod.UID)] - - // Generate hints. - cpuHints := p.generateCPUTopologyHints(available, reusable, requested) - klog.InfoS("TopologyHints generated", "pod", klog.KObj(pod), "containerName", container.Name, "cpuHints", cpuHints) - - return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): cpuHints, - } -} - -func (p *staticPolicy) GetPodTopologyHints(s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint { - // Get a count of how many guaranteed CPUs have been requested by Pod. - requested := p.podGuaranteedCPUs(pod) - - // Number of required CPUs is not an integer or a pod is not part of the Guaranteed QoS class. - // It will be treated by the TopologyManager as having no preference and cause it to ignore this - // resource when considering pod alignment. - // In terms of hints, this is equal to: TopologyHints[NUMANodeAffinity: nil, Preferred: true]. - if requested == 0 { - return nil - } - - assignedCPUs := cpuset.New() - for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { - requestedByContainer := p.guaranteedCPUs(pod, &container) - // Short circuit to regenerate the same hints if there are already - // guaranteed CPUs allocated to the Container. This might happen after a - // kubelet restart, for example. - if allocated, exists := s.GetCPUSet(string(pod.UID), container.Name); exists { - if allocated.Size() != requestedByContainer { - klog.InfoS("CPUs already allocated to container with different number than request", "pod", klog.KObj(pod), "containerName", container.Name, "allocatedSize", requested, "requestedByContainer", requestedByContainer, "allocatedSize", allocated.Size()) - // An empty list of hints will be treated as a preference that cannot be satisfied. - // In definition of hints this is equal to: TopologyHint[NUMANodeAffinity: nil, Preferred: false]. - // For all but the best-effort policy, the Topology Manager will throw a pod-admission error. - return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): {}, - } - } - // A set of CPUs already assigned to containers in this pod - assignedCPUs = assignedCPUs.Union(allocated) - } - } - if assignedCPUs.Size() == requested { - klog.InfoS("Regenerating TopologyHints for CPUs already allocated", "pod", klog.KObj(pod)) - return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): p.generateCPUTopologyHints(assignedCPUs, cpuset.CPUSet{}, requested), - } - } - - // Get a list of available CPUs. - available := p.GetAvailableCPUs(s) - - // Get a list of reusable CPUs (e.g. CPUs reused from initContainers). - // It should be an empty CPUSet for a newly created pod. - reusable := p.cpusToReuse[string(pod.UID)] - - // Ensure any CPUs already assigned to containers in this pod are included as part of the hint generation. - reusable = reusable.Union(assignedCPUs) - - // Generate hints. - cpuHints := p.generateCPUTopologyHints(available, reusable, requested) - klog.InfoS("TopologyHints generated", "pod", klog.KObj(pod), "cpuHints", cpuHints) - - return map[string][]topologymanager.TopologyHint{ - string(v1.ResourceCPU): cpuHints, - } -} - -// generateCPUTopologyHints generates a set of TopologyHints given the set of -// available CPUs and the number of CPUs being requested. -// -// It follows the convention of marking all hints that have the same number of -// bits set as the narrowest matching NUMANodeAffinity with 'Preferred: true', and -// marking all others with 'Preferred: false'. -func (p *staticPolicy) generateCPUTopologyHints(availableCPUs cpuset.CPUSet, reusableCPUs cpuset.CPUSet, request int) []topologymanager.TopologyHint { - // Initialize minAffinitySize to include all NUMA Nodes. - minAffinitySize := p.topology.CPUDetails.NUMANodes().Size() - - // Iterate through all combinations of numa nodes bitmask and build hints from them. - hints := []topologymanager.TopologyHint{} - bitmask.IterateBitMasks(p.topology.CPUDetails.NUMANodes().List(), func(mask bitmask.BitMask) { - // First, update minAffinitySize for the current request size. - cpusInMask := p.topology.CPUDetails.CPUsInNUMANodes(mask.GetBits()...).Size() - if cpusInMask >= request && mask.Count() < minAffinitySize { - minAffinitySize = mask.Count() - } - - // Then check to see if we have enough CPUs available on the current - // numa node bitmask to satisfy the CPU request. - numMatching := 0 - for _, c := range reusableCPUs.List() { - // Disregard this mask if its NUMANode isn't part of it. - if !mask.IsSet(p.topology.CPUDetails[c].NUMANodeID) { - return - } - numMatching++ - } - - // Finally, check to see if enough available CPUs remain on the current - // NUMA node combination to satisfy the CPU request. - for _, c := range availableCPUs.List() { - if mask.IsSet(p.topology.CPUDetails[c].NUMANodeID) { - numMatching++ - } - } - - // If they don't, then move onto the next combination. - if numMatching < request { - return - } - - // Otherwise, create a new hint from the numa node bitmask and add it to the - // list of hints. We set all hint preferences to 'false' on the first - // pass through. - hints = append(hints, topologymanager.TopologyHint{ - NUMANodeAffinity: mask, - Preferred: false, - }) - }) - - // Loop back through all hints and update the 'Preferred' field based on - // counting the number of bits sets in the affinity mask and comparing it - // to the minAffinitySize. Only those with an equal number of bits set (and - // with a minimal set of numa nodes) will be considered preferred. - for i := range hints { - if p.options.AlignBySocket && p.isHintSocketAligned(hints[i], minAffinitySize) { - hints[i].Preferred = true - continue - } - if hints[i].NUMANodeAffinity.Count() == minAffinitySize { - hints[i].Preferred = true - } - } - - return hints -} - -// isHintSocketAligned function return true if numa nodes in hint are socket aligned. -func (p *staticPolicy) isHintSocketAligned(hint topologymanager.TopologyHint, minAffinitySize int) bool { - numaNodesBitMask := hint.NUMANodeAffinity.GetBits() - numaNodesPerSocket := p.topology.NumNUMANodes / p.topology.NumSockets - if numaNodesPerSocket == 0 { - return false - } - // minSockets refers to minimum number of socket required to satify allocation. - // A hint is considered socket aligned if sockets across which numa nodes span is equal to minSockets - minSockets := (minAffinitySize + numaNodesPerSocket - 1) / numaNodesPerSocket - return p.topology.CPUDetails.SocketsInNUMANodes(numaNodesBitMask...).Size() == minSockets -} - -// getAlignedCPUs return set of aligned CPUs based on numa affinity mask and configured policy options. -func (p *staticPolicy) getAlignedCPUs(numaAffinity bitmask.BitMask, allocatableCPUs cpuset.CPUSet) cpuset.CPUSet { - alignedCPUs := cpuset.New() - numaBits := numaAffinity.GetBits() - - // If align-by-socket policy option is enabled, NUMA based hint is expanded to - // socket aligned hint. It will ensure that first socket aligned available CPUs are - // allocated before we try to find CPUs across socket to satisfy allocation request. - if p.options.AlignBySocket { - socketBits := p.topology.CPUDetails.SocketsInNUMANodes(numaBits...).UnsortedList() - for _, socketID := range socketBits { - alignedCPUs = alignedCPUs.Union(allocatableCPUs.Intersection(p.topology.CPUDetails.CPUsInSockets(socketID))) - } - return alignedCPUs - } - - for _, numaNodeID := range numaBits { - alignedCPUs = alignedCPUs.Union(allocatableCPUs.Intersection(p.topology.CPUDetails.CPUsInNUMANodes(numaNodeID))) - } - - return alignedCPUs -} - -func (p *staticPolicy) initializeMetrics(s state.State) { - metrics.CPUManagerSharedPoolSizeMilliCores.Set(float64(p.GetAvailableCPUs(s).Size() * 1000)) - metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedPhysicalCPU).Add(0) // ensure the value exists - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedPhysicalCPU).Add(0) // ensure the value exists - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedUncoreCache).Add(0) // ensure the value exists - totalAssignedCPUs := getTotalAssignedExclusiveCPUs(s) - metrics.CPUManagerExclusiveCPUsAllocationCount.Set(float64(totalAssignedCPUs.Size())) - updateAllocationPerNUMAMetric(p.topology, totalAssignedCPUs) -} - -func (p *staticPolicy) updateMetricsOnAllocate(s state.State, cpuAlloc topology.Allocation) { - ncpus := cpuAlloc.CPUs.Size() - metrics.CPUManagerExclusiveCPUsAllocationCount.Add(float64(ncpus)) - metrics.CPUManagerSharedPoolSizeMilliCores.Add(float64(-ncpus * 1000)) - if cpuAlloc.Aligned.UncoreCache { - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedUncoreCache).Inc() - } - totalAssignedCPUs := getTotalAssignedExclusiveCPUs(s) - updateAllocationPerNUMAMetric(p.topology, totalAssignedCPUs) -} - -func (p *staticPolicy) updateMetricsOnRelease(s state.State, cset cpuset.CPUSet) { - ncpus := cset.Size() - metrics.CPUManagerExclusiveCPUsAllocationCount.Add(float64(-ncpus)) - metrics.CPUManagerSharedPoolSizeMilliCores.Add(float64(ncpus * 1000)) - totalAssignedCPUs := getTotalAssignedExclusiveCPUs(s) - updateAllocationPerNUMAMetric(p.topology, totalAssignedCPUs.Difference(cset)) -} - -func getTotalAssignedExclusiveCPUs(s state.State) cpuset.CPUSet { - totalAssignedCPUs := cpuset.New() - for _, assignment := range s.GetCPUAssignments() { - for _, cset := range assignment { - totalAssignedCPUs = totalAssignedCPUs.Union(cset) - } - - } - return totalAssignedCPUs -} - -func updateAllocationPerNUMAMetric(topo *topology.CPUTopology, allocatedCPUs cpuset.CPUSet) { - numaCount := make(map[int]int) - - // Count CPUs allocated per NUMA node - for _, cpuID := range allocatedCPUs.UnsortedList() { - numaNode, err := topo.CPUNUMANodeID(cpuID) - if err != nil { - //NOTE: We are logging the error but it is highly unlikely to happen as the CPUset - // is already computed, evaluated and there is no room for user tampering. - klog.ErrorS(err, "Unable to determine NUMA node", "cpuID", cpuID) - } - numaCount[numaNode]++ - } - - // Update metric - for numaNode, count := range numaCount { - metrics.CPUManagerAllocationPerNUMA.WithLabelValues(strconv.Itoa(numaNode)).Set(float64(count)) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go deleted file mode 100644 index 564c3482c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/checkpoint.go +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "encoding/json" - "fmt" - "hash/fnv" - "strings" - - "k8s.io/apimachinery/pkg/util/dump" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" -) - -var _ checkpointmanager.Checkpoint = &CPUManagerCheckpointV1{} -var _ checkpointmanager.Checkpoint = &CPUManagerCheckpointV2{} -var _ checkpointmanager.Checkpoint = &CPUManagerCheckpoint{} - -// CPUManagerCheckpoint struct is used to store cpu/pod assignments in a checkpoint in v2 format -type CPUManagerCheckpoint struct { - PolicyName string `json:"policyName"` - DefaultCPUSet string `json:"defaultCpuSet"` - Entries map[string]map[string]string `json:"entries,omitempty"` - Checksum checksum.Checksum `json:"checksum"` -} - -// CPUManagerCheckpointV1 struct is used to store cpu/pod assignments in a checkpoint in v1 format -type CPUManagerCheckpointV1 struct { - PolicyName string `json:"policyName"` - DefaultCPUSet string `json:"defaultCpuSet"` - Entries map[string]string `json:"entries,omitempty"` - Checksum checksum.Checksum `json:"checksum"` -} - -// CPUManagerCheckpointV2 struct is used to store cpu/pod assignments in a checkpoint in v2 format -type CPUManagerCheckpointV2 = CPUManagerCheckpoint - -// NewCPUManagerCheckpoint returns an instance of Checkpoint -func NewCPUManagerCheckpoint() *CPUManagerCheckpoint { - //nolint:staticcheck // unexported-type-in-api user-facing error message - return newCPUManagerCheckpointV2() -} - -func newCPUManagerCheckpointV1() *CPUManagerCheckpointV1 { - return &CPUManagerCheckpointV1{ - Entries: make(map[string]string), - } -} - -func newCPUManagerCheckpointV2() *CPUManagerCheckpointV2 { - return &CPUManagerCheckpointV2{ - Entries: make(map[string]map[string]string), - } -} - -// MarshalCheckpoint returns marshalled checkpoint in v1 format -func (cp *CPUManagerCheckpointV1) MarshalCheckpoint() ([]byte, error) { - // make sure checksum wasn't set before so it doesn't affect output checksum - cp.Checksum = 0 - cp.Checksum = checksum.New(cp) - return json.Marshal(*cp) -} - -// MarshalCheckpoint returns marshalled checkpoint in v2 format -func (cp *CPUManagerCheckpointV2) MarshalCheckpoint() ([]byte, error) { - // make sure checksum wasn't set before so it doesn't affect output checksum - cp.Checksum = 0 - cp.Checksum = checksum.New(cp) - return json.Marshal(*cp) -} - -// UnmarshalCheckpoint tries to unmarshal passed bytes to checkpoint in v1 format -func (cp *CPUManagerCheckpointV1) UnmarshalCheckpoint(blob []byte) error { - return json.Unmarshal(blob, cp) -} - -// UnmarshalCheckpoint tries to unmarshal passed bytes to checkpoint in v2 format -func (cp *CPUManagerCheckpointV2) UnmarshalCheckpoint(blob []byte) error { - return json.Unmarshal(blob, cp) -} - -// VerifyChecksum verifies that current checksum of checkpoint is valid in v1 format -func (cp *CPUManagerCheckpointV1) VerifyChecksum() error { - if cp.Checksum == 0 { - // accept empty checksum for compatibility with old file backend - return nil - } - - ck := cp.Checksum - cp.Checksum = 0 - object := dump.ForHash(cp) - object = strings.Replace(object, "CPUManagerCheckpointV1", "CPUManagerCheckpoint", 1) - cp.Checksum = ck - - hash := fnv.New32a() - fmt.Fprintf(hash, "%v", object) - actualCS := checksum.Checksum(hash.Sum32()) - if cp.Checksum != actualCS { - return &errors.CorruptCheckpointError{ - ActualCS: uint64(actualCS), - ExpectedCS: uint64(cp.Checksum), - } - } - - return nil -} - -// VerifyChecksum verifies that current checksum of checkpoint is valid in v2 format -func (cp *CPUManagerCheckpointV2) VerifyChecksum() error { - if cp.Checksum == 0 { - // accept empty checksum for compatibility with old file backend - return nil - } - ck := cp.Checksum - cp.Checksum = 0 - err := ck.Verify(cp) - cp.Checksum = ck - return err -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go deleted file mode 100644 index 352fddfb9..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state.go +++ /dev/null @@ -1,58 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "k8s.io/utils/cpuset" -) - -// ContainerCPUAssignments type used in cpu manager state -type ContainerCPUAssignments map[string]map[string]cpuset.CPUSet - -// Clone returns a copy of ContainerCPUAssignments -func (as ContainerCPUAssignments) Clone() ContainerCPUAssignments { - ret := make(ContainerCPUAssignments, len(as)) - for pod := range as { - ret[pod] = make(map[string]cpuset.CPUSet, len(as[pod])) - for container, cset := range as[pod] { - ret[pod][container] = cset - } - } - return ret -} - -// Reader interface used to read current cpu/pod assignment state -type Reader interface { - GetCPUSet(podUID string, containerName string) (cpuset.CPUSet, bool) - GetDefaultCPUSet() cpuset.CPUSet - GetCPUSetOrDefault(podUID string, containerName string) cpuset.CPUSet - GetCPUAssignments() ContainerCPUAssignments -} - -type writer interface { - SetCPUSet(podUID string, containerName string, cpuset cpuset.CPUSet) - SetDefaultCPUSet(cpuset cpuset.CPUSet) - SetCPUAssignments(ContainerCPUAssignments) - Delete(podUID string, containerName string) - ClearState() -} - -// State interface provides methods for tracking and setting cpu/pod assignment -type State interface { - Reader - writer -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go deleted file mode 100644 index bda90ba1f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_checkpoint.go +++ /dev/null @@ -1,250 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "fmt" - "path/filepath" - "sync" - - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/utils/cpuset" -) - -var _ State = &stateCheckpoint{} - -type stateCheckpoint struct { - mux sync.RWMutex - policyName string - cache State - checkpointManager checkpointmanager.CheckpointManager - checkpointName string - initialContainers containermap.ContainerMap -} - -// NewCheckpointState creates new State for keeping track of cpu/pod assignment with checkpoint backend -func NewCheckpointState(stateDir, checkpointName, policyName string, initialContainers containermap.ContainerMap) (State, error) { - checkpointManager, err := checkpointmanager.NewCheckpointManager(stateDir) - if err != nil { - return nil, fmt.Errorf("failed to initialize checkpoint manager: %v", err) - } - stateCheckpoint := &stateCheckpoint{ - cache: NewMemoryState(), - policyName: policyName, - checkpointManager: checkpointManager, - checkpointName: checkpointName, - initialContainers: initialContainers, - } - - if err := stateCheckpoint.restoreState(); err != nil { - //nolint:staticcheck // ST1005 user-facing error message - return nil, fmt.Errorf("could not restore state from checkpoint: %v, please drain this node and delete the CPU manager checkpoint file %q before restarting Kubelet", - err, filepath.Join(stateDir, checkpointName)) - } - - return stateCheckpoint, nil -} - -// migrateV1CheckpointToV2Checkpoint() converts checkpoints from the v1 format to the v2 format -func (sc *stateCheckpoint) migrateV1CheckpointToV2Checkpoint(src *CPUManagerCheckpointV1, dst *CPUManagerCheckpointV2) error { - if src.PolicyName != "" { - dst.PolicyName = src.PolicyName - } - if src.DefaultCPUSet != "" { - dst.DefaultCPUSet = src.DefaultCPUSet - } - for containerID, cset := range src.Entries { - podUID, containerName, err := sc.initialContainers.GetContainerRef(containerID) - if err != nil { - return fmt.Errorf("containerID '%v' not found in initial containers list", containerID) - } - if dst.Entries == nil { - dst.Entries = make(map[string]map[string]string) - } - if _, exists := dst.Entries[podUID]; !exists { - dst.Entries[podUID] = make(map[string]string) - } - dst.Entries[podUID][containerName] = cset - } - return nil -} - -// restores state from a checkpoint and creates it if it doesn't exist -func (sc *stateCheckpoint) restoreState() error { - sc.mux.Lock() - defer sc.mux.Unlock() - var err error - - checkpointV1 := newCPUManagerCheckpointV1() - checkpointV2 := newCPUManagerCheckpointV2() - - if err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV1); err != nil { - checkpointV1 = &CPUManagerCheckpointV1{} // reset it back to 0 - if err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpointV2); err != nil { - if err == errors.ErrCheckpointNotFound { - return sc.storeState() - } - return err - } - } - - if err = sc.migrateV1CheckpointToV2Checkpoint(checkpointV1, checkpointV2); err != nil { - return fmt.Errorf("error migrating v1 checkpoint state to v2 checkpoint state: %s", err) - } - - if sc.policyName != checkpointV2.PolicyName { - return fmt.Errorf("configured policy %q differs from state checkpoint policy %q", sc.policyName, checkpointV2.PolicyName) - } - - var tmpDefaultCPUSet cpuset.CPUSet - if tmpDefaultCPUSet, err = cpuset.Parse(checkpointV2.DefaultCPUSet); err != nil { - return fmt.Errorf("could not parse default cpu set %q: %v", checkpointV2.DefaultCPUSet, err) - } - - var tmpContainerCPUSet cpuset.CPUSet - tmpAssignments := ContainerCPUAssignments{} - for pod := range checkpointV2.Entries { - tmpAssignments[pod] = make(map[string]cpuset.CPUSet, len(checkpointV2.Entries[pod])) - for container, cpuString := range checkpointV2.Entries[pod] { - if tmpContainerCPUSet, err = cpuset.Parse(cpuString); err != nil { - return fmt.Errorf("could not parse cpuset %q for container %q in pod %q: %v", cpuString, container, pod, err) - } - tmpAssignments[pod][container] = tmpContainerCPUSet - } - } - - sc.cache.SetDefaultCPUSet(tmpDefaultCPUSet) - sc.cache.SetCPUAssignments(tmpAssignments) - - klog.V(2).InfoS("State checkpoint: restored state from checkpoint") - klog.V(2).InfoS("State checkpoint: defaultCPUSet", "defaultCpuSet", tmpDefaultCPUSet.String()) - - return nil -} - -// saves state to a checkpoint, caller is responsible for locking -func (sc *stateCheckpoint) storeState() error { - checkpoint := NewCPUManagerCheckpoint() - checkpoint.PolicyName = sc.policyName - checkpoint.DefaultCPUSet = sc.cache.GetDefaultCPUSet().String() - - assignments := sc.cache.GetCPUAssignments() - for pod := range assignments { - checkpoint.Entries[pod] = make(map[string]string, len(assignments[pod])) - for container, cset := range assignments[pod] { - checkpoint.Entries[pod][container] = cset.String() - } - } - - err := sc.checkpointManager.CreateCheckpoint(sc.checkpointName, checkpoint) - if err != nil { - klog.ErrorS(err, "Failed to save checkpoint") - return err - } - return nil -} - -// GetCPUSet returns current CPU set -func (sc *stateCheckpoint) GetCPUSet(podUID string, containerName string) (cpuset.CPUSet, bool) { - sc.mux.RLock() - defer sc.mux.RUnlock() - - res, ok := sc.cache.GetCPUSet(podUID, containerName) - return res, ok -} - -// GetDefaultCPUSet returns default CPU set -func (sc *stateCheckpoint) GetDefaultCPUSet() cpuset.CPUSet { - sc.mux.RLock() - defer sc.mux.RUnlock() - - return sc.cache.GetDefaultCPUSet() -} - -// GetCPUSetOrDefault returns current CPU set, or default one if it wasn't changed -func (sc *stateCheckpoint) GetCPUSetOrDefault(podUID string, containerName string) cpuset.CPUSet { - sc.mux.RLock() - defer sc.mux.RUnlock() - - return sc.cache.GetCPUSetOrDefault(podUID, containerName) -} - -// GetCPUAssignments returns current CPU to pod assignments -func (sc *stateCheckpoint) GetCPUAssignments() ContainerCPUAssignments { - sc.mux.RLock() - defer sc.mux.RUnlock() - - return sc.cache.GetCPUAssignments() -} - -// SetCPUSet sets CPU set -func (sc *stateCheckpoint) SetCPUSet(podUID string, containerName string, cset cpuset.CPUSet) { - sc.mux.Lock() - defer sc.mux.Unlock() - sc.cache.SetCPUSet(podUID, containerName, cset) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint", "podUID", podUID, "containerName", containerName) - } -} - -// SetDefaultCPUSet sets default CPU set -func (sc *stateCheckpoint) SetDefaultCPUSet(cset cpuset.CPUSet) { - sc.mux.Lock() - defer sc.mux.Unlock() - sc.cache.SetDefaultCPUSet(cset) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint") - } -} - -// SetCPUAssignments sets CPU to pod assignments -func (sc *stateCheckpoint) SetCPUAssignments(a ContainerCPUAssignments) { - sc.mux.Lock() - defer sc.mux.Unlock() - sc.cache.SetCPUAssignments(a) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint") - } -} - -// Delete deletes assignment for specified pod -func (sc *stateCheckpoint) Delete(podUID string, containerName string) { - sc.mux.Lock() - defer sc.mux.Unlock() - sc.cache.Delete(podUID, containerName) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint", "podUID", podUID, "containerName", containerName) - } -} - -// ClearState clears the state and saves it in a checkpoint -func (sc *stateCheckpoint) ClearState() { - sc.mux.Lock() - defer sc.mux.Unlock() - sc.cache.ClearState() - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint") - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go deleted file mode 100644 index cb01ea926..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state/state_mem.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "sync" - - "k8s.io/klog/v2" - "k8s.io/utils/cpuset" -) - -type stateMemory struct { - sync.RWMutex - assignments ContainerCPUAssignments - defaultCPUSet cpuset.CPUSet -} - -var _ State = &stateMemory{} - -// NewMemoryState creates new State for keeping track of cpu/pod assignment -func NewMemoryState() State { - klog.InfoS("Initialized new in-memory state store") - return &stateMemory{ - assignments: ContainerCPUAssignments{}, - defaultCPUSet: cpuset.New(), - } -} - -func (s *stateMemory) GetCPUSet(podUID string, containerName string) (cpuset.CPUSet, bool) { - s.RLock() - defer s.RUnlock() - - res, ok := s.assignments[podUID][containerName] - return res.Clone(), ok -} - -func (s *stateMemory) GetDefaultCPUSet() cpuset.CPUSet { - s.RLock() - defer s.RUnlock() - - return s.defaultCPUSet.Clone() -} - -func (s *stateMemory) GetCPUSetOrDefault(podUID string, containerName string) cpuset.CPUSet { - if res, ok := s.GetCPUSet(podUID, containerName); ok { - return res - } - return s.GetDefaultCPUSet() -} - -func (s *stateMemory) GetCPUAssignments() ContainerCPUAssignments { - s.RLock() - defer s.RUnlock() - return s.assignments.Clone() -} - -func (s *stateMemory) SetCPUSet(podUID string, containerName string, cset cpuset.CPUSet) { - s.Lock() - defer s.Unlock() - - if _, ok := s.assignments[podUID]; !ok { - s.assignments[podUID] = make(map[string]cpuset.CPUSet) - } - - s.assignments[podUID][containerName] = cset - klog.InfoS("Updated desired CPUSet", "podUID", podUID, "containerName", containerName, "cpuSet", cset) -} - -func (s *stateMemory) SetDefaultCPUSet(cset cpuset.CPUSet) { - s.Lock() - defer s.Unlock() - - s.defaultCPUSet = cset - klog.InfoS("Updated default CPUSet", "cpuSet", cset) -} - -func (s *stateMemory) SetCPUAssignments(a ContainerCPUAssignments) { - s.Lock() - defer s.Unlock() - - s.assignments = a.Clone() - klog.InfoS("Updated CPUSet assignments", "assignments", a) -} - -func (s *stateMemory) Delete(podUID string, containerName string) { - s.Lock() - defer s.Unlock() - - delete(s.assignments[podUID], containerName) - if len(s.assignments[podUID]) == 0 { - delete(s.assignments, podUID) - } - klog.V(2).InfoS("Deleted CPUSet assignment", "podUID", podUID, "containerName", containerName) -} - -func (s *stateMemory) ClearState() { - s.Lock() - defer s.Unlock() - - s.defaultCPUSet = cpuset.CPUSet{} - s.assignments = make(ContainerCPUAssignments) - klog.V(2).InfoS("Cleared state") -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/alignment.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/alignment.go deleted file mode 100644 index 4f3dfe297..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/alignment.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 2025 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topology - -import ( - "fmt" - - "k8s.io/utils/cpuset" -) - -// Alignment is metadata about a cpuset allocation -type Alignment struct { - // UncoreCache is true if all the CPUs are uncore-cache aligned, - // IOW if they all share the same Uncore cache block. - // If the allocated CPU count is greater than a Uncore Group size, - // CPUs can't be uncore-aligned; otherwise, they are. - // This flag tracks alignment, not interference or lack thereof. - UncoreCache bool -} - -func (ca Alignment) String() string { - return fmt.Sprintf("aligned=", ca.UncoreCache) -} - -// Allocation represents a CPU set plus alignment metadata -type Allocation struct { - CPUs cpuset.CPUSet - Aligned Alignment -} - -func (ca Allocation) String() string { - return ca.CPUs.String() + " " + ca.Aligned.String() -} - -// EmptyAllocation returns a new zero-valued CPU allocation. Please note that -// a empty cpuset is aligned according to every possible way we can consider -func EmptyAllocation() Allocation { - return Allocation{ - CPUs: cpuset.New(), - Aligned: Alignment{ - UncoreCache: true, - }, - } -} - -func isAlignedAtUncoreCache(topo *CPUTopology, cpuList ...int) bool { - if len(cpuList) <= 1 { - return true - } - reference, ok := topo.CPUDetails[cpuList[0]] - if !ok { - return false - } - for _, cpu := range cpuList[1:] { - info, ok := topo.CPUDetails[cpu] - if !ok { - return false - } - if info.UncoreCacheID != reference.UncoreCacheID { - return false - } - } - return true -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/doc.go deleted file mode 100644 index 8a22c5db7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package topology contains helpers for the CPU manager. -package topology diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/topology.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/topology.go deleted file mode 100644 index 36291e6f5..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology/topology.go +++ /dev/null @@ -1,398 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topology - -import ( - "fmt" - - cadvisorapi "github.com/google/cadvisor/info/v1" - "k8s.io/klog/v2" - "k8s.io/utils/cpuset" -) - -// NUMANodeInfo is a map from NUMANode ID to a list of CPU IDs associated with -// that NUMANode. -type NUMANodeInfo map[int]cpuset.CPUSet - -// CPUDetails is a map from CPU ID to Core ID, Socket ID, and NUMA ID. -type CPUDetails map[int]CPUInfo - -// CPUTopology contains details of node cpu, where : -// CPU - logical CPU, cadvisor - thread -// Core - physical CPU, cadvisor - Core -// Socket - socket, cadvisor - Socket -// NUMA Node - NUMA cell, cadvisor - Node -// UncoreCache - Split L3 Cache Topology, cadvisor -type CPUTopology struct { - NumCPUs int - NumCores int - NumUncoreCache int - NumSockets int - NumNUMANodes int - CPUDetails CPUDetails -} - -// CPUsPerCore returns the number of logical CPUs are associated with -// each core. -func (topo *CPUTopology) CPUsPerCore() int { - if topo.NumCores == 0 { - return 0 - } - return topo.NumCPUs / topo.NumCores -} - -// CPUsPerSocket returns the number of logical CPUs are associated with -// each socket. -func (topo *CPUTopology) CPUsPerSocket() int { - if topo.NumSockets == 0 { - return 0 - } - return topo.NumCPUs / topo.NumSockets -} - -// CPUsPerUncore returns the number of logicial CPUs that are associated with -// each UncoreCache -func (topo *CPUTopology) CPUsPerUncore() int { - if topo.NumUncoreCache == 0 { - return 0 - } - return topo.NumCPUs / topo.NumUncoreCache -} - -// CPUCoreID returns the physical core ID which the given logical CPU -// belongs to. -func (topo *CPUTopology) CPUCoreID(cpu int) (int, error) { - info, ok := topo.CPUDetails[cpu] - if !ok { - return -1, fmt.Errorf("unknown CPU ID: %d", cpu) - } - return info.CoreID, nil -} - -// CPUCoreID returns the socket ID which the given logical CPU belongs to. -func (topo *CPUTopology) CPUSocketID(cpu int) (int, error) { - info, ok := topo.CPUDetails[cpu] - if !ok { - return -1, fmt.Errorf("unknown CPU ID: %d", cpu) - } - return info.SocketID, nil -} - -// CPUCoreID returns the NUMA node ID which the given logical CPU belongs to. -func (topo *CPUTopology) CPUNUMANodeID(cpu int) (int, error) { - info, ok := topo.CPUDetails[cpu] - if !ok { - return -1, fmt.Errorf("unknown CPU ID: %d", cpu) - } - return info.NUMANodeID, nil -} - -// CheckAlignment returns alignment information for the given cpuset in -// the context of the current CPU topology -func (topo *CPUTopology) CheckAlignment(cpus cpuset.CPUSet) Alignment { - cpuList := cpus.UnsortedList() - return Alignment{ - UncoreCache: isAlignedAtUncoreCache(topo, cpuList...), - } -} - -// CPUInfo contains the NUMA, socket, UncoreCache and core IDs associated with a CPU. -type CPUInfo struct { - NUMANodeID int - SocketID int - CoreID int - UncoreCacheID int -} - -// KeepOnly returns a new CPUDetails object with only the supplied cpus. -func (d CPUDetails) KeepOnly(cpus cpuset.CPUSet) CPUDetails { - result := CPUDetails{} - for cpu, info := range d { - if cpus.Contains(cpu) { - result[cpu] = info - } - } - return result -} - -// UncoreCaches returns all the uncorecache Id (L3 Index) associated with the CPUs in this CPUDetails -func (d CPUDetails) UncoreCaches() cpuset.CPUSet { - var numUnCoreIDs []int - for _, info := range d { - numUnCoreIDs = append(numUnCoreIDs, info.UncoreCacheID) - } - return cpuset.New(numUnCoreIDs...) -} - -// UnCoresInNUMANodes returns all of the uncore IDs associated with the given -// NUMANode IDs in this CPUDetails. -func (d CPUDetails) UncoreInNUMANodes(ids ...int) cpuset.CPUSet { - var unCoreIDs []int - for _, id := range ids { - for _, info := range d { - if info.NUMANodeID == id { - unCoreIDs = append(unCoreIDs, info.UncoreCacheID) - } - } - } - return cpuset.New(unCoreIDs...) -} - -// CoresNeededInUncoreCache returns either the full list of all available unique core IDs associated with the given -// UnCoreCache IDs in this CPUDetails or subset that matches the ask. -func (d CPUDetails) CoresNeededInUncoreCache(numCoresNeeded int, ids ...int) cpuset.CPUSet { - coreIDs := d.coresInUncoreCache(ids...) - if coreIDs.Size() <= numCoresNeeded { - return coreIDs - } - tmpCoreIDs := coreIDs.List() - return cpuset.New(tmpCoreIDs[:numCoresNeeded]...) -} - -// Helper function that just gets the cores -func (d CPUDetails) coresInUncoreCache(ids ...int) cpuset.CPUSet { - var coreIDs []int - for _, id := range ids { - for _, info := range d { - if info.UncoreCacheID == id { - coreIDs = append(coreIDs, info.CoreID) - } - } - } - return cpuset.New(coreIDs...) -} - -// CPUsInUncoreCaches returns all the logical CPU IDs associated with the given -// UnCoreCache IDs in this CPUDetails -func (d CPUDetails) CPUsInUncoreCaches(ids ...int) cpuset.CPUSet { - var cpuIDs []int - for _, id := range ids { - for cpu, info := range d { - if info.UncoreCacheID == id { - cpuIDs = append(cpuIDs, cpu) - } - } - } - return cpuset.New(cpuIDs...) -} - -// NUMANodes returns all of the NUMANode IDs associated with the CPUs in this -// CPUDetails. -func (d CPUDetails) NUMANodes() cpuset.CPUSet { - var numaNodeIDs []int - for _, info := range d { - numaNodeIDs = append(numaNodeIDs, info.NUMANodeID) - } - return cpuset.New(numaNodeIDs...) -} - -// NUMANodesInSockets returns all of the logical NUMANode IDs associated with -// the given socket IDs in this CPUDetails. -func (d CPUDetails) NUMANodesInSockets(ids ...int) cpuset.CPUSet { - var numaNodeIDs []int - for _, id := range ids { - for _, info := range d { - if info.SocketID == id { - numaNodeIDs = append(numaNodeIDs, info.NUMANodeID) - } - } - } - return cpuset.New(numaNodeIDs...) -} - -// Sockets returns all of the socket IDs associated with the CPUs in this -// CPUDetails. -func (d CPUDetails) Sockets() cpuset.CPUSet { - var socketIDs []int - for _, info := range d { - socketIDs = append(socketIDs, info.SocketID) - } - return cpuset.New(socketIDs...) -} - -// CPUsInSockets returns all of the logical CPU IDs associated with the given -// socket IDs in this CPUDetails. -func (d CPUDetails) CPUsInSockets(ids ...int) cpuset.CPUSet { - var cpuIDs []int - for _, id := range ids { - for cpu, info := range d { - if info.SocketID == id { - cpuIDs = append(cpuIDs, cpu) - } - } - } - return cpuset.New(cpuIDs...) -} - -// SocketsInNUMANodes returns all of the logical Socket IDs associated with the -// given NUMANode IDs in this CPUDetails. -func (d CPUDetails) SocketsInNUMANodes(ids ...int) cpuset.CPUSet { - var socketIDs []int - for _, id := range ids { - for _, info := range d { - if info.NUMANodeID == id { - socketIDs = append(socketIDs, info.SocketID) - } - } - } - return cpuset.New(socketIDs...) -} - -// Cores returns all of the core IDs associated with the CPUs in this -// CPUDetails. -func (d CPUDetails) Cores() cpuset.CPUSet { - var coreIDs []int - for _, info := range d { - coreIDs = append(coreIDs, info.CoreID) - } - return cpuset.New(coreIDs...) -} - -// CoresInNUMANodes returns all of the core IDs associated with the given -// NUMANode IDs in this CPUDetails. -func (d CPUDetails) CoresInNUMANodes(ids ...int) cpuset.CPUSet { - var coreIDs []int - for _, id := range ids { - for _, info := range d { - if info.NUMANodeID == id { - coreIDs = append(coreIDs, info.CoreID) - } - } - } - return cpuset.New(coreIDs...) -} - -// CoresInSockets returns all of the core IDs associated with the given socket -// IDs in this CPUDetails. -func (d CPUDetails) CoresInSockets(ids ...int) cpuset.CPUSet { - var coreIDs []int - for _, id := range ids { - for _, info := range d { - if info.SocketID == id { - coreIDs = append(coreIDs, info.CoreID) - } - } - } - return cpuset.New(coreIDs...) -} - -// CPUs returns all of the logical CPU IDs in this CPUDetails. -func (d CPUDetails) CPUs() cpuset.CPUSet { - var cpuIDs []int - for cpuID := range d { - cpuIDs = append(cpuIDs, cpuID) - } - return cpuset.New(cpuIDs...) -} - -// CPUsInNUMANodes returns all of the logical CPU IDs associated with the given -// NUMANode IDs in this CPUDetails. -func (d CPUDetails) CPUsInNUMANodes(ids ...int) cpuset.CPUSet { - var cpuIDs []int - for _, id := range ids { - for cpu, info := range d { - if info.NUMANodeID == id { - cpuIDs = append(cpuIDs, cpu) - } - } - } - return cpuset.New(cpuIDs...) -} - -// CPUsInCores returns all of the logical CPU IDs associated with the given -// core IDs in this CPUDetails. -func (d CPUDetails) CPUsInCores(ids ...int) cpuset.CPUSet { - var cpuIDs []int - for _, id := range ids { - for cpu, info := range d { - if info.CoreID == id { - cpuIDs = append(cpuIDs, cpu) - } - } - } - return cpuset.New(cpuIDs...) -} - -func getUncoreCacheID(core cadvisorapi.Core) int { - if len(core.UncoreCaches) < 1 { - // In case cAdvisor is nil, failback to socket alignment since uncorecache is not shared - return core.SocketID - } - // Even though cadvisor API returns a slice, we only expect either 0 or a 1 uncore caches, - // so everything past the first entry should be discarded or ignored - return core.UncoreCaches[0].Id -} - -// Discover returns CPUTopology based on cadvisor node info -func Discover(machineInfo *cadvisorapi.MachineInfo) (*CPUTopology, error) { - if machineInfo.NumCores == 0 { - return nil, fmt.Errorf("could not detect number of cpus") - } - - CPUDetails := CPUDetails{} - numPhysicalCores := 0 - - for _, node := range machineInfo.Topology { - numPhysicalCores += len(node.Cores) - for _, core := range node.Cores { - if coreID, err := getUniqueCoreID(core.Threads); err == nil { - for _, cpu := range core.Threads { - CPUDetails[cpu] = CPUInfo{ - CoreID: coreID, - SocketID: core.SocketID, - NUMANodeID: node.Id, - UncoreCacheID: getUncoreCacheID(core), - } - } - } else { - klog.ErrorS(nil, "Could not get unique coreID for socket", "socket", core.SocketID, "core", core.Id, "threads", core.Threads) - return nil, err - } - } - } - - return &CPUTopology{ - NumCPUs: machineInfo.NumCores, - NumSockets: machineInfo.NumSockets, - NumCores: numPhysicalCores, - NumNUMANodes: CPUDetails.NUMANodes().Size(), - NumUncoreCache: CPUDetails.UncoreCaches().Size(), - CPUDetails: CPUDetails, - }, nil -} - -// getUniqueCoreID computes coreId as the lowest cpuID -// for a given Threads []int slice. This will assure that coreID's are -// platform unique (opposite to what cAdvisor reports) -func getUniqueCoreID(threads []int) (coreID int, err error) { - if len(threads) == 0 { - return 0, fmt.Errorf("no cpus provided") - } - - if len(threads) != cpuset.New(threads...).Size() { - return 0, fmt.Errorf("cpus provided are not unique") - } - - min := threads[0] - for _, thread := range threads[1:] { - if thread < min { - min = thread - } - } - - return min, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/OWNERS b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/OWNERS deleted file mode 100644 index 5c8da238f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: [] -reviewers: - - klueska -emeritus_approvers: - - vishh - - jiayingz diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint/checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint/checkpoint.go deleted file mode 100644 index b9dcdaf82..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint/checkpoint.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package checkpoint - -import ( - "encoding/json" - - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum" -) - -// DeviceManagerCheckpoint defines the operations to retrieve pod devices -type DeviceManagerCheckpoint interface { - checkpointmanager.Checkpoint - GetData() ([]PodDevicesEntry, map[string][]string) -} - -// DevicesPerNUMA represents device ids obtained from device plugin per NUMA node id -type DevicesPerNUMA map[int64][]string - -// PodDevicesEntry connects pod information to devices -type PodDevicesEntry struct { - PodUID string - ContainerName string - ResourceName string - DeviceIDs DevicesPerNUMA - AllocResp []byte -} - -// checkpointData struct is used to store pod to device allocation information -// in a checkpoint file. -// TODO: add version control when we need to change checkpoint format. -type checkpointData struct { - PodDeviceEntries []PodDevicesEntry - RegisteredDevices map[string][]string -} - -// Data holds checkpoint data and its checksum -type Data struct { - Data checkpointData - Checksum checksum.Checksum -} - -// NewDevicesPerNUMA is a function that creates DevicesPerNUMA map -func NewDevicesPerNUMA() DevicesPerNUMA { - return make(DevicesPerNUMA) -} - -// Devices is a function that returns all device ids for all NUMA nodes -// and represent it as sets.Set[string] -func (dev DevicesPerNUMA) Devices() sets.Set[string] { - result := sets.New[string]() - - for _, devs := range dev { - result.Insert(devs...) - } - return result -} - -// New returns an instance of Checkpoint - must be an alias for the most recent version -func New(devEntries []PodDevicesEntry, devices map[string][]string) DeviceManagerCheckpoint { - return newV2(devEntries, devices) -} - -func newV2(devEntries []PodDevicesEntry, devices map[string][]string) DeviceManagerCheckpoint { - return &Data{ - Data: checkpointData{ - PodDeviceEntries: devEntries, - RegisteredDevices: devices, - }, - } -} - -// MarshalCheckpoint returns marshalled data -func (cp *Data) MarshalCheckpoint() ([]byte, error) { - cp.Checksum = checksum.New(cp.Data) - return json.Marshal(*cp) -} - -// UnmarshalCheckpoint returns unmarshalled data -func (cp *Data) UnmarshalCheckpoint(blob []byte) error { - return json.Unmarshal(blob, cp) -} - -// VerifyChecksum verifies that passed checksum is same as calculated checksum -func (cp *Data) VerifyChecksum() error { - return cp.Checksum.Verify(cp.Data) -} - -// GetData returns device entries and registered devices in the *most recent* -// checkpoint format, *not* in the original format stored on disk. -func (cp *Data) GetData() ([]PodDevicesEntry, map[string][]string) { - return cp.Data.PodDeviceEntries, cp.Data.RegisteredDevices -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/endpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/endpoint.go deleted file mode 100644 index a9f7e7bed..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/endpoint.go +++ /dev/null @@ -1,123 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package devicemanager - -import ( - "context" - "fmt" - "sync" - "time" - - pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" - plugin "k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1" -) - -// endpoint maps to a single registered device plugin. It is responsible -// for managing gRPC communications with the device plugin and caching -// device states reported by the device plugin. -type endpoint interface { - getPreferredAllocation(available, mustInclude []string, size int) (*pluginapi.PreferredAllocationResponse, error) - allocate(devs []string) (*pluginapi.AllocateResponse, error) - preStartContainer(devs []string) (*pluginapi.PreStartContainerResponse, error) - setStopTime(t time.Time) - isStopped() bool - stopGracePeriodExpired() bool -} - -type endpointImpl struct { - mutex sync.Mutex - resourceName string - api pluginapi.DevicePluginClient - stopTime time.Time - client plugin.Client // for testing only -} - -// newEndpointImpl creates a new endpoint for the given resourceName. -// This is to be used during normal device plugin registration. -func newEndpointImpl(p plugin.DevicePlugin) *endpointImpl { - return &endpointImpl{ - api: p.API(), - resourceName: p.Resource(), - } -} - -// newStoppedEndpointImpl creates a new endpoint for the given resourceName with stopTime set. -// This is to be used during Kubelet restart, before the actual device plugin re-registers. -func newStoppedEndpointImpl(resourceName string) *endpointImpl { - return &endpointImpl{ - resourceName: resourceName, - stopTime: time.Now(), - } -} - -func (e *endpointImpl) isStopped() bool { - e.mutex.Lock() - defer e.mutex.Unlock() - return !e.stopTime.IsZero() -} - -func (e *endpointImpl) stopGracePeriodExpired() bool { - e.mutex.Lock() - defer e.mutex.Unlock() - return !e.stopTime.IsZero() && time.Since(e.stopTime) > endpointStopGracePeriod -} - -func (e *endpointImpl) setStopTime(t time.Time) { - e.mutex.Lock() - defer e.mutex.Unlock() - e.stopTime = t -} - -// getPreferredAllocation issues GetPreferredAllocation gRPC call to the device plugin. -func (e *endpointImpl) getPreferredAllocation(available, mustInclude []string, size int) (*pluginapi.PreferredAllocationResponse, error) { - if e.isStopped() { - return nil, fmt.Errorf(errEndpointStopped, e) - } - return e.api.GetPreferredAllocation(context.Background(), &pluginapi.PreferredAllocationRequest{ - ContainerRequests: []*pluginapi.ContainerPreferredAllocationRequest{ - { - AvailableDeviceIDs: available, - MustIncludeDeviceIDs: mustInclude, - AllocationSize: int32(size), - }, - }, - }) -} - -// allocate issues Allocate gRPC call to the device plugin. -func (e *endpointImpl) allocate(devs []string) (*pluginapi.AllocateResponse, error) { - if e.isStopped() { - return nil, fmt.Errorf(errEndpointStopped, e) - } - return e.api.Allocate(context.Background(), &pluginapi.AllocateRequest{ - ContainerRequests: []*pluginapi.ContainerAllocateRequest{ - {DevicesIDs: devs}, - }, - }) -} - -// preStartContainer issues PreStartContainer gRPC call to the device plugin. -func (e *endpointImpl) preStartContainer(devs []string) (*pluginapi.PreStartContainerResponse, error) { - if e.isStopped() { - return nil, fmt.Errorf(errEndpointStopped, e) - } - ctx, cancel := context.WithTimeout(context.Background(), pluginapi.KubeletPreStartContainerRPCTimeoutInSecs*time.Second) - defer cancel() - return e.api.PreStartContainer(ctx, &pluginapi.PreStartContainerRequest{ - DevicesIDs: devs, - }) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go deleted file mode 100644 index 9ed9c1322..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/manager.go +++ /dev/null @@ -1,1185 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package devicemanager - -import ( - "context" - goerrors "errors" - "fmt" - "os" - "path/filepath" - "runtime" - "sort" - "sync" - "time" - - cadvisorapi "github.com/google/cadvisor/info/v1" - "k8s.io/klog/v2" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - errorsutil "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apiserver/pkg/server/healthz" - utilfeature "k8s.io/apiserver/pkg/util/feature" - pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint" - plugin "k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1" - "k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/config" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" - "k8s.io/kubernetes/pkg/kubelet/metrics" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" - schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" -) - -const nodeWithoutTopology = -1 - -// ActivePodsFunc is a function that returns a list of pods to reconcile. -type ActivePodsFunc func() []*v1.Pod - -// ManagerImpl is the structure in charge of managing Device Plugins. -type ManagerImpl struct { - checkpointdir string - - endpoints map[string]endpointInfo // Key is ResourceName - mutex sync.Mutex - - server plugin.Server - - // activePods is a method for listing active pods on the node - // so the amount of pluginResources requested by existing pods - // could be counted when updating allocated devices - activePods ActivePodsFunc - - // sourcesReady provides the readiness of kubelet configuration sources such as apiserver update readiness. - // We use it to determine when we can purge inactive pods from checkpointed state. - sourcesReady config.SourcesReady - - // allDevices holds all the devices currently registered to the device manager - allDevices ResourceDeviceInstances - - // healthyDevices contains all the registered healthy resourceNames and their exported device IDs. - healthyDevices map[string]sets.Set[string] - - // unhealthyDevices contains all the unhealthy devices and their exported device IDs. - unhealthyDevices map[string]sets.Set[string] - - // allocatedDevices contains allocated deviceIds, keyed by resourceName. - allocatedDevices map[string]sets.Set[string] - - // podDevices contains pod to allocated device mapping. - podDevices *podDevices - checkpointManager checkpointmanager.CheckpointManager - - // List of NUMA Nodes available on the underlying machine - numaNodes []int - - // Store of Topology Affinities that the Device Manager can query. - topologyAffinityStore topologymanager.Store - - // devicesToReuse contains devices that can be reused as they have been allocated to - // init containers. - devicesToReuse PodReusableDevices - - // containerMap provides a mapping from (pod, container) -> containerID - // for all containers in a pod. Used to detect pods running across a restart - containerMap containermap.ContainerMap - - // containerRunningSet identifies which container among those present in `containerMap` - // was reported running by the container runtime when `containerMap` was computed. - // Used to detect pods running across a restart - containerRunningSet sets.Set[string] - - // update channel for device health updates - update chan resourceupdates.Update -} - -type endpointInfo struct { - e endpoint - opts *pluginapi.DevicePluginOptions -} - -type sourcesReadyStub struct{} - -// PodReusableDevices is a map by pod name of devices to reuse. -type PodReusableDevices map[string]map[string]sets.Set[string] - -func (s *sourcesReadyStub) AddSource(source string) {} -func (s *sourcesReadyStub) AllReady() bool { return true } - -// NewManagerImpl creates a new manager. -func NewManagerImpl(topology []cadvisorapi.Node, topologyAffinityStore topologymanager.Store) (*ManagerImpl, error) { - socketPath := pluginapi.KubeletSocket - if runtime.GOOS == "windows" { - socketPath = os.Getenv("SYSTEMDRIVE") + pluginapi.KubeletSocketWindows - } - return newManagerImpl(socketPath, topology, topologyAffinityStore) -} - -func newManagerImpl(socketPath string, topology []cadvisorapi.Node, topologyAffinityStore topologymanager.Store) (*ManagerImpl, error) { - klog.V(2).InfoS("Creating Device Plugin manager", "path", socketPath) - - var numaNodes []int - for _, node := range topology { - numaNodes = append(numaNodes, node.Id) - } - - manager := &ManagerImpl{ - endpoints: make(map[string]endpointInfo), - - allDevices: NewResourceDeviceInstances(), - healthyDevices: make(map[string]sets.Set[string]), - unhealthyDevices: make(map[string]sets.Set[string]), - allocatedDevices: make(map[string]sets.Set[string]), - podDevices: newPodDevices(), - numaNodes: numaNodes, - topologyAffinityStore: topologyAffinityStore, - devicesToReuse: make(PodReusableDevices), - update: make(chan resourceupdates.Update, 100), - } - - server, err := plugin.NewServer(socketPath, manager, manager) - if err != nil { - return nil, fmt.Errorf("failed to create plugin server: %v", err) - } - - manager.server = server - manager.checkpointdir, _ = filepath.Split(server.SocketPath()) - - // The following structures are populated with real implementations in manager.Start() - // Before that, initializes them to perform no-op operations. - manager.activePods = func() []*v1.Pod { return []*v1.Pod{} } - manager.sourcesReady = &sourcesReadyStub{} - checkpointManager, err := checkpointmanager.NewCheckpointManager(manager.checkpointdir) - if err != nil { - return nil, fmt.Errorf("failed to initialize checkpoint manager: %v", err) - } - manager.checkpointManager = checkpointManager - - return manager, nil -} - -func (m *ManagerImpl) Updates() <-chan resourceupdates.Update { - return m.update -} - -// CleanupPluginDirectory is to remove all existing unix sockets -// from /var/lib/kubelet/device-plugins on Device Plugin Manager start -func (m *ManagerImpl) CleanupPluginDirectory(dir string) error { - d, err := os.Open(dir) - if err != nil { - return err - } - defer d.Close() - names, err := d.Readdirnames(-1) - if err != nil { - return err - } - var errs []error - for _, name := range names { - filePath := filepath.Join(dir, name) - if filePath == m.checkpointFile() { - continue - } - stat, err := os.Stat(filePath) - if err != nil { - klog.ErrorS(err, "Failed to stat file", "path", filePath) - continue - } - if stat.IsDir() || stat.Mode()&os.ModeSocket == 0 { - continue - } - err = os.RemoveAll(filePath) - if err != nil { - errs = append(errs, err) - klog.ErrorS(err, "Failed to remove file", "path", filePath) - continue - } - } - return errorsutil.NewAggregate(errs) -} - -// PluginConnected is to connect a plugin to a new endpoint. -// This is done as part of device plugin registration. -func (m *ManagerImpl) PluginConnected(resourceName string, p plugin.DevicePlugin) error { - options, err := p.API().GetDevicePluginOptions(context.Background(), &pluginapi.Empty{}) - if err != nil { - return fmt.Errorf("failed to get device plugin options: %v", err) - } - - e := newEndpointImpl(p) - - m.mutex.Lock() - defer m.mutex.Unlock() - m.endpoints[resourceName] = endpointInfo{e, options} - - klog.V(2).InfoS("Device plugin connected", "resourceName", resourceName) - return nil -} - -// PluginDisconnected is to disconnect a plugin from an endpoint. -// This is done as part of device plugin deregistration. -func (m *ManagerImpl) PluginDisconnected(resourceName string) { - m.mutex.Lock() - defer m.mutex.Unlock() - - if ep, exists := m.endpoints[resourceName]; exists { - m.markResourceUnhealthy(resourceName) - klog.V(2).InfoS("Endpoint became unhealthy", "resourceName", resourceName, "endpoint", ep) - - ep.e.setStopTime(time.Now()) - } -} - -// PluginListAndWatchReceiver receives ListAndWatchResponse from a device plugin -// and ensures that an upto date state (e.g. number of devices and device health) -// is captured. Also, registered device and device to container allocation -// information is checkpointed to the disk. -func (m *ManagerImpl) PluginListAndWatchReceiver(resourceName string, resp *pluginapi.ListAndWatchResponse) { - var devices []pluginapi.Device - for _, d := range resp.Devices { - devices = append(devices, *d) - } - m.genericDeviceUpdateCallback(resourceName, devices) -} - -func (m *ManagerImpl) genericDeviceUpdateCallback(resourceName string, devices []pluginapi.Device) { - healthyCount := 0 - m.mutex.Lock() - m.healthyDevices[resourceName] = sets.New[string]() - m.unhealthyDevices[resourceName] = sets.New[string]() - oldDevices := m.allDevices[resourceName] - podsToUpdate := sets.New[string]() - m.allDevices[resourceName] = make(map[string]pluginapi.Device) - for _, dev := range devices { - - if utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatus) { - // compare with old device's health and send update to the channel if needed - updatePodUIDFn := func(deviceID string) { - podUID, _ := m.podDevices.getPodAndContainerForDevice(deviceID) - if podUID != "" { - podsToUpdate.Insert(podUID) - } - } - if oldDev, ok := oldDevices[dev.ID]; ok { - if oldDev.Health != dev.Health { - updatePodUIDFn(dev.ID) - } - } else { - // if this is a new device, it might have existed before and disappeared for a while - // but still be assigned to a Pod. In this case, we need to send an update to the channel - updatePodUIDFn(dev.ID) - } - } - - m.allDevices[resourceName][dev.ID] = dev - if dev.Health == pluginapi.Healthy { - m.healthyDevices[resourceName].Insert(dev.ID) - healthyCount++ - } else { - m.unhealthyDevices[resourceName].Insert(dev.ID) - } - } - m.mutex.Unlock() - - if utilfeature.DefaultFeatureGate.Enabled(features.ResourceHealthStatus) { - if len(podsToUpdate) > 0 { - select { - case m.update <- resourceupdates.Update{PodUIDs: podsToUpdate.UnsortedList()}: - default: - klog.ErrorS(goerrors.New("device update channel is full"), "discard pods info", "podsToUpdate", podsToUpdate.UnsortedList()) - } - } - } - - if err := m.writeCheckpoint(); err != nil { - klog.ErrorS(err, "Writing checkpoint encountered") - } - klog.V(2).InfoS("Processed device updates for resource", "resourceName", resourceName, "totalCount", len(devices), "healthyCount", healthyCount) -} - -// GetWatcherHandler returns the plugin handler -func (m *ManagerImpl) GetWatcherHandler() cache.PluginHandler { - return m.server -} - -// GetHealthChecker returns the plugin handler -func (m *ManagerImpl) GetHealthChecker() healthz.HealthChecker { - return m.server -} - -// checkpointFile returns device plugin checkpoint file path. -func (m *ManagerImpl) checkpointFile() string { - return filepath.Join(m.checkpointdir, kubeletDeviceManagerCheckpoint) -} - -// Start starts the Device Plugin Manager and start initialization of -// podDevices and allocatedDevices information from checkpointed state and -// starts device plugin registration service. -func (m *ManagerImpl) Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, initialContainers containermap.ContainerMap, initialContainerRunningSet sets.Set[string]) error { - klog.V(2).InfoS("Starting Device Plugin manager") - - m.activePods = activePods - m.sourcesReady = sourcesReady - m.containerMap = initialContainers - m.containerRunningSet = initialContainerRunningSet - - // Loads in allocatedDevices information from disk. - err := m.readCheckpoint() - if err != nil { - klog.ErrorS(err, "Continue after failing to read checkpoint file. Device allocation info may NOT be up-to-date") - } - - return m.server.Start() -} - -// Stop is the function that can stop the plugin server. -// Can be called concurrently, more than once, and is safe to call -// without a prior Start. -func (m *ManagerImpl) Stop() error { - return m.server.Stop() -} - -// Allocate is the call that you can use to allocate a set of devices -// from the registered device plugins. -func (m *ManagerImpl) Allocate(pod *v1.Pod, container *v1.Container) error { - if _, ok := m.devicesToReuse[string(pod.UID)]; !ok { - m.devicesToReuse[string(pod.UID)] = make(map[string]sets.Set[string]) - } - // If pod entries to m.devicesToReuse other than the current pod exist, delete them. - for podUID := range m.devicesToReuse { - if podUID != string(pod.UID) { - delete(m.devicesToReuse, podUID) - } - } - // Allocate resources for init containers first as we know the caller always loops - // through init containers before looping through app containers. Should the caller - // ever change those semantics, this logic will need to be amended. - for _, initContainer := range pod.Spec.InitContainers { - if container.Name == initContainer.Name { - if err := m.allocateContainerResources(pod, container, m.devicesToReuse[string(pod.UID)]); err != nil { - return err - } - if !podutil.IsRestartableInitContainer(&initContainer) { - m.podDevices.addContainerAllocatedResources(string(pod.UID), container.Name, m.devicesToReuse[string(pod.UID)]) - } else { - // If the init container is restartable, we need to keep the - // devices allocated. In other words, we should remove them - // from the devicesToReuse. - m.podDevices.removeContainerAllocatedResources(string(pod.UID), container.Name, m.devicesToReuse[string(pod.UID)]) - } - return nil - } - } - if err := m.allocateContainerResources(pod, container, m.devicesToReuse[string(pod.UID)]); err != nil { - return err - } - m.podDevices.removeContainerAllocatedResources(string(pod.UID), container.Name, m.devicesToReuse[string(pod.UID)]) - return nil -} - -// UpdatePluginResources updates node resources based on devices already allocated to pods. -func (m *ManagerImpl) UpdatePluginResources(node *schedulerframework.NodeInfo, attrs *lifecycle.PodAdmitAttributes) error { - pod := attrs.Pod - - // quick return if no pluginResources requested - if !m.podDevices.hasPod(string(pod.UID)) { - return nil - } - - m.sanitizeNodeAllocatable(node) - return nil -} - -func (m *ManagerImpl) markResourceUnhealthy(resourceName string) { - klog.V(2).InfoS("Mark all resources Unhealthy for resource", "resourceName", resourceName) - healthyDevices := sets.New[string]() - if _, ok := m.healthyDevices[resourceName]; ok { - healthyDevices = m.healthyDevices[resourceName] - m.healthyDevices[resourceName] = sets.New[string]() - } - if _, ok := m.unhealthyDevices[resourceName]; !ok { - m.unhealthyDevices[resourceName] = sets.New[string]() - } - m.unhealthyDevices[resourceName] = m.unhealthyDevices[resourceName].Union(healthyDevices) -} - -// GetCapacity is expected to be called when Kubelet updates its node status. -// The first returned variable contains the registered device plugin resource capacity. -// The second returned variable contains the registered device plugin resource allocatable. -// The third returned variable contains previously registered resources that are no longer active. -// Kubelet uses this information to update resource capacity/allocatable in its node status. -// After the call, device plugin can remove the inactive resources from its internal list as the -// change is already reflected in Kubelet node status. -// Note in the special case after Kubelet restarts, device plugin resource capacities can -// temporarily drop to zero till corresponding device plugins re-register. This is OK because -// cm.UpdatePluginResource() run during predicate Admit guarantees we adjust nodeinfo -// capacity for already allocated pods so that they can continue to run. However, new pods -// requiring device plugin resources will not be scheduled till device plugin re-registers. -func (m *ManagerImpl) GetCapacity() (v1.ResourceList, v1.ResourceList, []string) { - needsUpdateCheckpoint := false - var capacity = v1.ResourceList{} - var allocatable = v1.ResourceList{} - deletedResources := sets.New[string]() - m.mutex.Lock() - for resourceName, devices := range m.healthyDevices { - eI, ok := m.endpoints[resourceName] - if (ok && eI.e.stopGracePeriodExpired()) || !ok { - // The resources contained in endpoints and (un)healthyDevices - // should always be consistent. Otherwise, we run with the risk - // of failing to garbage collect non-existing resources or devices. - if !ok { - klog.InfoS("Unexpected: healthyDevices and endpoints are out of sync") - } - delete(m.endpoints, resourceName) - delete(m.healthyDevices, resourceName) - deletedResources.Insert(resourceName) - needsUpdateCheckpoint = true - } else { - capacity[v1.ResourceName(resourceName)] = *resource.NewQuantity(int64(devices.Len()), resource.DecimalSI) - allocatable[v1.ResourceName(resourceName)] = *resource.NewQuantity(int64(devices.Len()), resource.DecimalSI) - } - } - for resourceName, devices := range m.unhealthyDevices { - eI, ok := m.endpoints[resourceName] - if (ok && eI.e.stopGracePeriodExpired()) || !ok { - if !ok { - klog.InfoS("Unexpected: unhealthyDevices and endpoints became out of sync") - } - delete(m.endpoints, resourceName) - delete(m.unhealthyDevices, resourceName) - deletedResources.Insert(resourceName) - needsUpdateCheckpoint = true - } else { - capacityCount := capacity[v1.ResourceName(resourceName)] - unhealthyCount := *resource.NewQuantity(int64(devices.Len()), resource.DecimalSI) - capacityCount.Add(unhealthyCount) - capacity[v1.ResourceName(resourceName)] = capacityCount - } - } - m.mutex.Unlock() - if needsUpdateCheckpoint { - if err := m.writeCheckpoint(); err != nil { - klog.ErrorS(err, "Failed to write checkpoint file") - } - } - return capacity, allocatable, deletedResources.UnsortedList() -} - -// Checkpoints device to container allocation information to disk. -func (m *ManagerImpl) writeCheckpoint() error { - m.mutex.Lock() - registeredDevs := make(map[string][]string) - for resource, devices := range m.healthyDevices { - registeredDevs[resource] = devices.UnsortedList() - } - data := checkpoint.New(m.podDevices.toCheckpointData(), - registeredDevs) - m.mutex.Unlock() - err := m.checkpointManager.CreateCheckpoint(kubeletDeviceManagerCheckpoint, data) - if err != nil { - err2 := fmt.Errorf("failed to write checkpoint file %q: %v", kubeletDeviceManagerCheckpoint, err) - klog.ErrorS(err, "Failed to write checkpoint file") - return err2 - } - klog.V(4).InfoS("Checkpoint file written", "checkpoint", kubeletDeviceManagerCheckpoint) - return nil -} - -// Reads device to container allocation information from disk, and populates -// m.allocatedDevices accordingly. -func (m *ManagerImpl) readCheckpoint() error { - cp, err := m.getCheckpoint() - if err != nil { - if err == errors.ErrCheckpointNotFound { - // no point in trying anything else - klog.ErrorS(err, "Failed to read data from checkpoint", "checkpoint", kubeletDeviceManagerCheckpoint) - return nil - } - return err - } - - m.mutex.Lock() - defer m.mutex.Unlock() - podDevices, registeredDevs := cp.GetData() - m.podDevices.fromCheckpointData(podDevices) - m.allocatedDevices = m.podDevices.devices() - for resource := range registeredDevs { - // During start up, creates empty healthyDevices list so that the resource capacity - // will stay zero till the corresponding device plugin re-registers. - m.healthyDevices[resource] = sets.New[string]() - m.unhealthyDevices[resource] = sets.New[string]() - m.endpoints[resource] = endpointInfo{e: newStoppedEndpointImpl(resource), opts: nil} - } - - klog.V(4).InfoS("Read data from checkpoint file", "checkpoint", kubeletDeviceManagerCheckpoint) - return nil -} - -func (m *ManagerImpl) getCheckpoint() (checkpoint.DeviceManagerCheckpoint, error) { - registeredDevs := make(map[string][]string) - devEntries := make([]checkpoint.PodDevicesEntry, 0) - cp := checkpoint.New(devEntries, registeredDevs) - err := m.checkpointManager.GetCheckpoint(kubeletDeviceManagerCheckpoint, cp) - return cp, err -} - -// UpdateAllocatedDevices frees any Devices that are bound to terminated pods. -func (m *ManagerImpl) UpdateAllocatedDevices() { - activePods := m.activePods() - if !m.sourcesReady.AllReady() { - return - } - m.mutex.Lock() - defer m.mutex.Unlock() - podsToBeRemoved := m.podDevices.pods() - for _, pod := range activePods { - podsToBeRemoved.Delete(string(pod.UID)) - } - if len(podsToBeRemoved) <= 0 { - return - } - klog.V(3).InfoS("Pods to be removed", "podUIDs", sets.List(podsToBeRemoved)) - m.podDevices.delete(sets.List(podsToBeRemoved)) - // Regenerated allocatedDevices after we update pod allocation information. - m.allocatedDevices = m.podDevices.devices() -} - -// Returns list of device Ids we need to allocate with Allocate rpc call. -// Returns empty list in case we don't need to issue the Allocate rpc call. -func (m *ManagerImpl) devicesToAllocate(podUID, contName, resource string, required int, reusableDevices sets.Set[string]) (sets.Set[string], error) { - m.mutex.Lock() - defer m.mutex.Unlock() - needed := required - // Gets list of devices that have already been allocated. - // This can happen if a container restarts for example. - devices := m.podDevices.containerDevices(podUID, contName, resource) - if devices != nil { - klog.V(3).InfoS("Found pre-allocated devices for resource on pod", "resourceName", resource, "containerName", contName, "podUID", podUID, "devices", sets.List(devices)) - needed = needed - devices.Len() - // A pod's resource is not expected to change once admitted by the API server, - // so just fail loudly here. We can revisit this part if this no longer holds. - if needed != 0 { - return nil, fmt.Errorf("pod %q container %q changed request for resource %q from %d to %d", podUID, contName, resource, devices.Len(), required) - } - } - - // We have 3 major flows to handle: - // 1. kubelet running, normal allocation (needed > 0, container being [re]created). Steady state and most common case by far and large. - // 2. kubelet restart. In this scenario every other component of the stack (device plugins, app container, runtime) is still running. - // 3. node reboot. In this scenario device plugins may not be running yet when we try to allocate devices. - // note: if we get this far the runtime is surely running. This is usually enforced at OS level by startup system services dependencies. - - // First we take care of the exceptional flow (scenarios 2 and 3). In both flows, kubelet is reinitializing, and while kubelet is initializing, sources are NOT all ready. - // Is this a simple kubelet restart (scenario 2)? To distinguish, we use the information we got for runtime. If we are asked to allocate devices for containers reported - // running, then it can only be a kubelet restart. On node reboot the runtime and the containers were also shut down. Then, if the container was running, it can only be - // because it already has access to all the required devices, so we got nothing to do and we can bail out. - if !m.sourcesReady.AllReady() && m.isContainerAlreadyRunning(podUID, contName) { - klog.V(3).InfoS("Container detected running, nothing to do", "deviceNumber", needed, "resourceName", resource, "podUID", podUID, "containerName", contName) - return nil, nil - } - - // We dealt with scenario 2. If we got this far it's either scenario 3 (node reboot) or scenario 1 (steady state, normal flow). - klog.V(3).InfoS("Need devices to allocate for pod", "deviceNumber", needed, "resourceName", resource, "podUID", podUID, "containerName", contName) - healthyDevices, hasRegistered := m.healthyDevices[resource] - - // The following checks are expected to fail only happen on scenario 3 (node reboot). - // The kubelet is reinitializing and got a container from sources. But there's no ordering, so an app container may attempt allocation _before_ the device plugin was created, - // has registered and reported back to kubelet the devices. - // This can only happen on scenario 3 because at steady state (scenario 1) the scheduler prevents pod to be sent towards node which don't report enough devices. - // Note: we need to check the device health and registration status *before* we check how many devices are needed, doing otherwise caused issue #109595 - // Note: if the scheduler is bypassed, we fall back in scenario 1, so we still need these checks. - if !hasRegistered { - return nil, fmt.Errorf("cannot allocate unregistered device %s", resource) - } - - // Check if registered resource has healthy devices - if healthyDevices.Len() == 0 { - return nil, fmt.Errorf("no healthy devices present; cannot allocate unhealthy devices %s", resource) - } - - // Check if all the previously allocated devices are healthy - if !healthyDevices.IsSuperset(devices) { - return nil, fmt.Errorf("previously allocated devices are no longer healthy; cannot allocate unhealthy devices %s", resource) - } - - // We handled the known error paths in scenario 3 (node reboot), so from now on we can fall back in a common path. - // We cover container restart on kubelet steady state with the same flow. - if needed == 0 { - klog.V(3).InfoS("No devices needed, nothing to do", "deviceNumber", needed, "resourceName", resource, "podUID", podUID, "containerName", contName) - // No change, no work. - return nil, nil - } - - // Declare the list of allocated devices. - // This will be populated and returned below. - allocated := sets.New[string]() - - // Create a closure to help with device allocation - // Returns 'true' once no more devices need to be allocated. - allocateRemainingFrom := func(devices sets.Set[string]) bool { - // When we call callGetPreferredAllocationIfAvailable below, we will release - // the lock and call the device plugin. If someone calls ListResource concurrently, - // device manager will recalculate the allocatedDevices map. Some entries with - // empty sets may be removed, so we reinit here. - if m.allocatedDevices[resource] == nil { - m.allocatedDevices[resource] = sets.New[string]() - } - for device := range devices.Difference(allocated) { - m.allocatedDevices[resource].Insert(device) - allocated.Insert(device) - needed-- - if needed == 0 { - return true - } - } - return false - } - - // Allocates from reusableDevices list first. - if allocateRemainingFrom(reusableDevices) { - return allocated, nil - } - - // Gets Devices in use. - devicesInUse := m.allocatedDevices[resource] - // Gets Available devices. - available := m.healthyDevices[resource].Difference(devicesInUse) - if available.Len() < needed { - return nil, fmt.Errorf("requested number of devices unavailable for %s. Requested: %d, Available: %d", resource, needed, available.Len()) - } - - // Filters available Devices based on NUMA affinity. - aligned, unaligned, noAffinity := m.filterByAffinity(podUID, contName, resource, available) - - // If we can allocate all remaining devices from the set of aligned ones, then - // give the plugin the chance to influence which ones to allocate from that set. - if needed < aligned.Len() { - // First allocate from the preferred devices list (if available). - preferred, err := m.callGetPreferredAllocationIfAvailable(podUID, contName, resource, aligned.Union(allocated), allocated, required) - if err != nil { - return nil, err - } - if allocateRemainingFrom(preferred.Intersection(aligned)) { - return allocated, nil - } - // Then fallback to allocate from the aligned set if no preferred list - // is returned (or not enough devices are returned in that list). - if allocateRemainingFrom(aligned) { - return allocated, nil - } - - return nil, fmt.Errorf("unexpectedly allocated less resources than required. Requested: %d, Got: %d", required, required-needed) - } - - // If we can't allocate all remaining devices from the set of aligned ones, - // then start by first allocating all the aligned devices (to ensure - // that the alignment guaranteed by the TopologyManager is honored). - if allocateRemainingFrom(aligned) { - return allocated, nil - } - - // Then give the plugin the chance to influence the decision on any - // remaining devices to allocate. - preferred, err := m.callGetPreferredAllocationIfAvailable(podUID, contName, resource, available.Union(allocated), allocated, required) - if err != nil { - return nil, err - } - if allocateRemainingFrom(preferred.Intersection(available)) { - return allocated, nil - } - - // Finally, if the plugin did not return a preferred allocation (or didn't - // return a large enough one), then fall back to allocating the remaining - // devices from the 'unaligned' and 'noAffinity' sets. - if allocateRemainingFrom(unaligned) { - return allocated, nil - } - if allocateRemainingFrom(noAffinity) { - return allocated, nil - } - - return nil, fmt.Errorf("unexpectedly allocated less resources than required. Requested: %d, Got: %d", required, required-needed) -} - -func (m *ManagerImpl) filterByAffinity(podUID, contName, resource string, available sets.Set[string]) (sets.Set[string], sets.Set[string], sets.Set[string]) { - // If alignment information is not available, just pass the available list back. - hint := m.topologyAffinityStore.GetAffinity(podUID, contName) - if !m.deviceHasTopologyAlignment(resource) || hint.NUMANodeAffinity == nil { - return sets.New[string](), sets.New[string](), available - } - - // Build a map of NUMA Nodes to the devices associated with them. A - // device may be associated to multiple NUMA nodes at the same time. If an - // available device does not have any NUMA Nodes associated with it, add it - // to a list of NUMA Nodes for the fake NUMANode -1. - perNodeDevices := make(map[int]sets.Set[string]) - for d := range available { - if m.allDevices[resource][d].Topology == nil || len(m.allDevices[resource][d].Topology.Nodes) == 0 { - if _, ok := perNodeDevices[nodeWithoutTopology]; !ok { - perNodeDevices[nodeWithoutTopology] = sets.New[string]() - } - perNodeDevices[nodeWithoutTopology].Insert(d) - continue - } - - for _, node := range m.allDevices[resource][d].Topology.Nodes { - if _, ok := perNodeDevices[int(node.ID)]; !ok { - perNodeDevices[int(node.ID)] = sets.New[string]() - } - perNodeDevices[int(node.ID)].Insert(d) - } - } - - // Get a flat list of all the nodes associated with available devices. - var nodes []int - for node := range perNodeDevices { - nodes = append(nodes, node) - } - - // Sort the list of nodes by: - // 1) Nodes contained in the 'hint's affinity set - // 2) Nodes not contained in the 'hint's affinity set - // 3) The fake NUMANode of -1 (assuming it is included in the list) - // Within each of the groups above, sort the nodes by how many devices they contain - sort.Slice(nodes, func(i, j int) bool { - // If one or the other of nodes[i] or nodes[j] is in the 'hint's affinity set - if hint.NUMANodeAffinity.IsSet(nodes[i]) && hint.NUMANodeAffinity.IsSet(nodes[j]) { - return perNodeDevices[nodes[i]].Len() < perNodeDevices[nodes[j]].Len() - } - if hint.NUMANodeAffinity.IsSet(nodes[i]) { - return true - } - if hint.NUMANodeAffinity.IsSet(nodes[j]) { - return false - } - - // If one or the other of nodes[i] or nodes[j] is the fake NUMA node -1 (they can't both be) - if nodes[i] == nodeWithoutTopology { - return false - } - if nodes[j] == nodeWithoutTopology { - return true - } - - // Otherwise both nodes[i] and nodes[j] are real NUMA nodes that are not in the 'hint's' affinity list. - return perNodeDevices[nodes[i]].Len() < perNodeDevices[nodes[j]].Len() - }) - - // Generate three sorted lists of devices. Devices in the first list come - // from valid NUMA Nodes contained in the affinity mask. Devices in the - // second list come from valid NUMA Nodes not in the affinity mask. Devices - // in the third list come from devices with no NUMA Node association (i.e. - // those mapped to the fake NUMA Node -1). Because we loop through the - // sorted list of NUMA nodes in order, within each list, devices are sorted - // by their connection to NUMA Nodes with more devices on them. - var fromAffinity []string - var notFromAffinity []string - var withoutTopology []string - for d := range available { - // Since the same device may be associated with multiple NUMA Nodes. We - // need to be careful not to add each device to multiple lists. The - // logic below ensures this by breaking after the first NUMA node that - // has the device is encountered. - for _, n := range nodes { - if perNodeDevices[n].Has(d) { - if n == nodeWithoutTopology { - withoutTopology = append(withoutTopology, d) - } else if hint.NUMANodeAffinity.IsSet(n) { - fromAffinity = append(fromAffinity, d) - } else { - notFromAffinity = append(notFromAffinity, d) - } - break - } - } - } - - // Return all three lists containing the full set of devices across them. - return sets.New[string](fromAffinity...), sets.New[string](notFromAffinity...), sets.New[string](withoutTopology...) -} - -// allocateContainerResources attempts to allocate all of required device -// plugin resources for the input container, issues an Allocate rpc request -// for each new device resource requirement, processes their AllocateResponses, -// and updates the cached containerDevices on success. -func (m *ManagerImpl) allocateContainerResources(pod *v1.Pod, container *v1.Container, devicesToReuse map[string]sets.Set[string]) error { - podUID := string(pod.UID) - contName := container.Name - allocatedDevicesUpdated := false - needsUpdateCheckpoint := false - // Extended resources are not allowed to be overcommitted. - // Since device plugin advertises extended resources, - // therefore Requests must be equal to Limits and iterating - // over the Limits should be sufficient. - for k, v := range container.Resources.Limits { - resource := string(k) - needed := int(v.Value()) - klog.V(3).InfoS("Looking for needed resources", "resourceName", resource, "pod", klog.KObj(pod), "containerName", container.Name, "needed", needed) - if !m.isDevicePluginResource(resource) { - continue - } - // Updates allocatedDevices to garbage collect any stranded resources - // before doing the device plugin allocation. - if !allocatedDevicesUpdated { - m.UpdateAllocatedDevices() - allocatedDevicesUpdated = true - } - allocDevices, err := m.devicesToAllocate(podUID, contName, resource, needed, devicesToReuse[resource]) - if err != nil { - return err - } - if allocDevices == nil || len(allocDevices) <= 0 { - continue - } - - needsUpdateCheckpoint = true - - startRPCTime := time.Now() - // Manager.Allocate involves RPC calls to device plugin, which - // could be heavy-weight. Therefore we want to perform this operation outside - // mutex lock. Note if Allocate call fails, we may leave container resources - // partially allocated for the failed container. We rely on UpdateAllocatedDevices() - // to garbage collect these resources later. Another side effect is that if - // we have X resource A and Y resource B in total, and two containers, container1 - // and container2 both require X resource A and Y resource B. Both allocation - // requests may fail if we serve them in mixed order. - // TODO: may revisit this part later if we see inefficient resource allocation - // in real use as the result of this. Should also consider to parallelize device - // plugin Allocate grpc calls if it becomes common that a container may require - // resources from multiple device plugins. - m.mutex.Lock() - eI, ok := m.endpoints[resource] - m.mutex.Unlock() - if !ok { - m.mutex.Lock() - m.allocatedDevices = m.podDevices.devices() - m.mutex.Unlock() - return fmt.Errorf("unknown Device Plugin %s", resource) - } - - devs := allocDevices.UnsortedList() - // TODO: refactor this part of code to just append a ContainerAllocationRequest - // in a passed in AllocateRequest pointer, and issues a single Allocate call per pod. - klog.V(4).InfoS("Making allocation request for device plugin", "devices", devs, "resourceName", resource, "pod", klog.KObj(pod), "containerName", container.Name) - resp, err := eI.e.allocate(devs) - metrics.DevicePluginAllocationDuration.WithLabelValues(resource).Observe(metrics.SinceInSeconds(startRPCTime)) - if err != nil { - // In case of allocation failure, we want to restore m.allocatedDevices - // to the actual allocated state from m.podDevices. - m.mutex.Lock() - m.allocatedDevices = m.podDevices.devices() - m.mutex.Unlock() - return err - } - - if len(resp.ContainerResponses) == 0 { - return fmt.Errorf("no containers return in allocation response %v", resp) - } - - allocDevicesWithNUMA := checkpoint.NewDevicesPerNUMA() - // Update internal cached podDevices state. - m.mutex.Lock() - for dev := range allocDevices { - if m.allDevices[resource][dev].Topology == nil || len(m.allDevices[resource][dev].Topology.Nodes) == 0 { - allocDevicesWithNUMA[nodeWithoutTopology] = append(allocDevicesWithNUMA[nodeWithoutTopology], dev) - continue - } - for idx := range m.allDevices[resource][dev].Topology.Nodes { - node := m.allDevices[resource][dev].Topology.Nodes[idx] - allocDevicesWithNUMA[node.ID] = append(allocDevicesWithNUMA[node.ID], dev) - } - } - m.mutex.Unlock() - m.podDevices.insert(podUID, contName, resource, allocDevicesWithNUMA, resp.ContainerResponses[0]) - } - - if needsUpdateCheckpoint { - return m.writeCheckpoint() - } - - return nil -} - -// checkPodActive checks if the given pod is still in activePods list -func (m *ManagerImpl) checkPodActive(pod *v1.Pod) bool { - activePods := m.activePods() - for _, activePod := range activePods { - if activePod.UID == pod.UID { - return true - } - } - - return false -} - -// GetDeviceRunContainerOptions checks whether we have cached containerDevices -// for the passed-in and returns its DeviceRunContainerOptions -// for the found one. An empty struct is returned in case no cached state is found. -func (m *ManagerImpl) GetDeviceRunContainerOptions(pod *v1.Pod, container *v1.Container) (*DeviceRunContainerOptions, error) { - podUID := string(pod.UID) - contName := container.Name - needsReAllocate := false - for k, v := range container.Resources.Limits { - resource := string(k) - if !m.isDevicePluginResource(resource) || v.Value() == 0 { - continue - } - err := m.callPreStartContainerIfNeeded(podUID, contName, resource) - if err != nil { - return nil, err - } - - if !m.checkPodActive(pod) { - klog.V(5).InfoS("Pod deleted from activePods, skip to reAllocate", "pod", klog.KObj(pod), "podUID", podUID, "containerName", container.Name) - continue - } - - // This is a device plugin resource yet we don't have cached - // resource state. This is likely due to a race during node - // restart. We re-issue allocate request to cover this race. - if m.podDevices.containerDevices(podUID, contName, resource) == nil { - needsReAllocate = true - } - } - if needsReAllocate { - klog.V(2).InfoS("Needs to re-allocate device plugin resources for pod", "pod", klog.KObj(pod), "containerName", container.Name) - if err := m.Allocate(pod, container); err != nil { - return nil, err - } - } - return m.podDevices.deviceRunContainerOptions(string(pod.UID), container.Name), nil -} - -// callPreStartContainerIfNeeded issues PreStartContainer grpc call for device plugin resource -// with PreStartRequired option set. -func (m *ManagerImpl) callPreStartContainerIfNeeded(podUID, contName, resource string) error { - m.mutex.Lock() - eI, ok := m.endpoints[resource] - if !ok { - m.mutex.Unlock() - return fmt.Errorf("endpoint not found in cache for a registered resource: %s", resource) - } - - if eI.opts == nil || !eI.opts.PreStartRequired { - m.mutex.Unlock() - klog.V(5).InfoS("Plugin options indicate to skip PreStartContainer for resource", "podUID", podUID, "resourceName", resource, "containerName", contName) - return nil - } - - devices := m.podDevices.containerDevices(podUID, contName, resource) - if devices == nil { - m.mutex.Unlock() - return fmt.Errorf("no devices found allocated in local cache for pod %s, container %s, resource %s", podUID, contName, resource) - } - - m.mutex.Unlock() - devs := devices.UnsortedList() - klog.V(4).InfoS("Issuing a PreStartContainer call for container", "containerName", contName, "podUID", podUID) - _, err := eI.e.preStartContainer(devs) - if err != nil { - return fmt.Errorf("device plugin PreStartContainer rpc failed with err: %v", err) - } - // TODO: Add metrics support for init RPC - return nil -} - -// callGetPreferredAllocationIfAvailable issues GetPreferredAllocation grpc -// call for device plugin resource with GetPreferredAllocationAvailable option set. -func (m *ManagerImpl) callGetPreferredAllocationIfAvailable(podUID, contName, resource string, available, mustInclude sets.Set[string], size int) (sets.Set[string], error) { - eI, ok := m.endpoints[resource] - if !ok { - return nil, fmt.Errorf("endpoint not found in cache for a registered resource: %s", resource) - } - - if eI.opts == nil || !eI.opts.GetPreferredAllocationAvailable { - klog.V(5).InfoS("Plugin options indicate to skip GetPreferredAllocation for resource", "resourceName", resource, "podUID", podUID, "containerName", contName) - return nil, nil - } - - m.mutex.Unlock() - klog.V(4).InfoS("Issuing a GetPreferredAllocation call for container", "resourceName", resource, "containerName", contName, "podUID", podUID) - resp, err := eI.e.getPreferredAllocation(available.UnsortedList(), mustInclude.UnsortedList(), size) - m.mutex.Lock() - if err != nil { - return nil, fmt.Errorf("device plugin GetPreferredAllocation rpc failed with err: %v", err) - } - if resp != nil && len(resp.ContainerResponses) > 0 { - return sets.New[string](resp.ContainerResponses[0].DeviceIDs...), nil - } - return sets.New[string](), nil -} - -// sanitizeNodeAllocatable scans through allocatedDevices in the device manager -// and if necessary, updates allocatableResource in nodeInfo to at least equal to -// the allocated capacity. This allows pods that have already been scheduled on -// the node to pass GeneralPredicates admission checking even upon device plugin failure. -func (m *ManagerImpl) sanitizeNodeAllocatable(node *schedulerframework.NodeInfo) { - var newAllocatableResource *schedulerframework.Resource - allocatableResource := node.Allocatable - if allocatableResource.ScalarResources == nil { - allocatableResource.ScalarResources = make(map[v1.ResourceName]int64) - } - - m.mutex.Lock() - defer m.mutex.Unlock() - for resource, devices := range m.allocatedDevices { - needed := devices.Len() - quant, ok := allocatableResource.ScalarResources[v1.ResourceName(resource)] - if ok && int(quant) >= needed { - continue - } - // Needs to update nodeInfo.AllocatableResource to make sure - // NodeInfo.allocatableResource at least equal to the capacity already allocated. - if newAllocatableResource == nil { - newAllocatableResource = allocatableResource.Clone() - } - newAllocatableResource.ScalarResources[v1.ResourceName(resource)] = int64(needed) - } - if newAllocatableResource != nil { - node.Allocatable = newAllocatableResource - } -} - -func (m *ManagerImpl) isDevicePluginResource(resource string) bool { - m.mutex.Lock() - defer m.mutex.Unlock() - _, registeredResource := m.healthyDevices[resource] - _, allocatedResource := m.allocatedDevices[resource] - // Return true if this is either an active device plugin resource or - // a resource we have previously allocated. - if registeredResource || allocatedResource { - return true - } - return false -} - -// GetAllocatableDevices returns information about all the healthy devices known to the manager -func (m *ManagerImpl) GetAllocatableDevices() ResourceDeviceInstances { - m.mutex.Lock() - defer m.mutex.Unlock() - resp := m.allDevices.Filter(m.healthyDevices) - klog.V(4).InfoS("GetAllocatableDevices", "known", len(m.allDevices), "allocatable", len(resp)) - return resp -} - -// GetDevices returns the devices used by the specified container -func (m *ManagerImpl) GetDevices(podUID, containerName string) ResourceDeviceInstances { - return m.podDevices.getContainerDevices(podUID, containerName) -} - -func (m *ManagerImpl) UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStatus) { - m.mutex.Lock() - defer m.mutex.Unlock() - - // Today we ignore edge cases that are not likely to happen: - // - update statuses for containers that are in spec, but not in status - // - update statuses for resources requested in spec, but with no information in podDevices - for i, containerStatus := range status.ContainerStatuses { - devices := m.podDevices.getContainerDevices(string(pod.UID), containerStatus.Name) - - for resourceName, deviceInstances := range devices { - for id, d := range deviceInstances { - health := pluginapi.Healthy - // this is unlikely, but check for existence here anyways - if r, ok := m.allDevices[resourceName]; ok { - if _, ok := r[id]; ok { - health = m.allDevices[resourceName][id].Health - } - } - - d.Health = health - - deviceInstances[id] = d - } - } - - for resourceName, dI := range devices { - resourceStatus := v1.ResourceStatus{ - Name: v1.ResourceName(resourceName), - Resources: []v1.ResourceHealth{}, - } - - for id, d := range dI { - health := v1.ResourceHealthStatusHealthy - if d.Health != pluginapi.Healthy { - health = v1.ResourceHealthStatusUnhealthy - } - resourceStatus.Resources = append(resourceStatus.Resources, v1.ResourceHealth{ - ResourceID: v1.ResourceID(id), - Health: health, - }) - } - - if status.ContainerStatuses[i].AllocatedResourcesStatus == nil { - status.ContainerStatuses[i].AllocatedResourcesStatus = []v1.ResourceStatus{} - } - - // look up the resource status by name and update it - found := false - for j, rs := range status.ContainerStatuses[i].AllocatedResourcesStatus { - if rs.Name == resourceStatus.Name { - status.ContainerStatuses[i].AllocatedResourcesStatus[j] = resourceStatus - found = true - break - } - } - - if !found { - status.ContainerStatuses[i].AllocatedResourcesStatus = append(status.ContainerStatuses[i].AllocatedResourcesStatus, resourceStatus) - } - } - } -} - -// ShouldResetExtendedResourceCapacity returns whether the extended resources should be zeroed or not, -// depending on whether the node has been recreated. Absence of the checkpoint file strongly indicates the node -// has been recreated. -func (m *ManagerImpl) ShouldResetExtendedResourceCapacity() bool { - checkpoints, err := m.checkpointManager.ListCheckpoints() - if err != nil { - return false - } - return len(checkpoints) == 0 -} - -func (m *ManagerImpl) isContainerAlreadyRunning(podUID, cntName string) bool { - cntID, err := m.containerMap.GetContainerID(podUID, cntName) - if err != nil { - klog.ErrorS(err, "Container not found in the initial map, assumed NOT running", "podUID", podUID, "containerName", cntName) - return false - } - - // note that if container runtime is down when kubelet restarts, this set will be empty, - // so on kubelet restart containers will again fail admission, hitting https://github.com/kubernetes/kubernetes/issues/118559 again. - // This scenario should however be rare enough. - if !m.containerRunningSet.Has(cntID) { - klog.V(4).InfoS("Container not present in the initial running set", "podUID", podUID, "containerName", cntName, "containerID", cntID) - return false - } - - // Once we make it here we know we have a running container. - klog.V(4).InfoS("Container found in the initial set, assumed running", "podUID", podUID, "containerName", cntName, "containerID", cntID) - return true -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/api.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/api.go deleted file mode 100644 index f84cd551f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/api.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - api "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" -) - -// RegistrationHandler is an interface for handling device plugin registration -// and plugin directory cleanup. -type RegistrationHandler interface { - CleanupPluginDirectory(string) error -} - -// ClientHandler is an interface for handling device plugin connections. -type ClientHandler interface { - PluginConnected(string, DevicePlugin) error - PluginDisconnected(string) - PluginListAndWatchReceiver(string, *api.ListAndWatchResponse) -} - -// TODO: evaluate whether we need these error definitions. -const ( - // errFailedToDialDevicePlugin is the error raised when the device plugin could not be - // reached on the registered socket - errFailedToDialDevicePlugin = "failed to dial device plugin:" - // errUnsupportedVersion is the error raised when the device plugin uses an API version not - // supported by the Kubelet registry - errUnsupportedVersion = "requested API version %q is not supported by kubelet. Supported version is %q" - // errInvalidResourceName is the error raised when a device plugin is registering - // itself with an invalid ResourceName - errInvalidResourceName = "the ResourceName %q is invalid" - // errBadSocket is the error raised when the registry socket path is not absolute - errBadSocket = "bad socketPath, must be an absolute path:" -) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go deleted file mode 100644 index 98359ab32..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/client.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - "context" - "fmt" - "net" - "sync" - "time" - - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - - "k8s.io/klog/v2" - api "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" -) - -// DevicePlugin interface provides methods for accessing Device Plugin resources, API and unix socket. -type DevicePlugin interface { - API() api.DevicePluginClient - Resource() string - SocketPath() string -} - -// Client interface provides methods for establishing/closing gRPC connection and running the device plugin gRPC client. -type Client interface { - Connect() error - Run() - Disconnect() error -} - -type client struct { - mutex sync.Mutex - resource string - socket string - grpc *grpc.ClientConn - handler ClientHandler - client api.DevicePluginClient -} - -// NewPluginClient returns an initialized device plugin client. -func NewPluginClient(r string, socketPath string, h ClientHandler) Client { - return &client{ - resource: r, - socket: socketPath, - handler: h, - } -} - -// Connect is for establishing a gRPC connection between device manager and device plugin. -func (c *client) Connect() error { - client, conn, err := dial(c.socket) - if err != nil { - klog.ErrorS(err, "Unable to connect to device plugin client with socket path", "path", c.socket) - return err - } - c.mutex.Lock() - c.grpc = conn - c.client = client - c.mutex.Unlock() - return c.handler.PluginConnected(c.resource, c) -} - -// Run is for running the device plugin gRPC client. -func (c *client) Run() { - stream, err := c.client.ListAndWatch(context.Background(), &api.Empty{}) - if err != nil { - klog.ErrorS(err, "ListAndWatch ended unexpectedly for device plugin", "resource", c.resource) - return - } - - for { - response, err := stream.Recv() - if err != nil { - klog.ErrorS(err, "ListAndWatch ended unexpectedly for device plugin", "resource", c.resource) - return - } - klog.V(2).InfoS("State pushed for device plugin", "resource", c.resource, "resourceCapacity", len(response.Devices)) - c.handler.PluginListAndWatchReceiver(c.resource, response) - } -} - -// Disconnect is for closing gRPC connection between device manager and device plugin. -func (c *client) Disconnect() error { - c.mutex.Lock() - if c.grpc != nil { - if err := c.grpc.Close(); err != nil { - klog.V(2).ErrorS(err, "Failed to close grcp connection", "resource", c.Resource()) - } - c.grpc = nil - } - c.mutex.Unlock() - c.handler.PluginDisconnected(c.resource) - - klog.V(2).InfoS("Device plugin disconnected", "resource", c.resource) - return nil -} - -func (c *client) Resource() string { - return c.resource -} - -func (c *client) API() api.DevicePluginClient { - return c.client -} - -func (c *client) SocketPath() string { - return c.socket -} - -// dial establishes the gRPC communication with the registered device plugin. https://godoc.org/google.golang.org/grpc#Dial -func dial(unixSocketPath string) (api.DevicePluginClient, *grpc.ClientConn, error) { - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - c, err := grpc.DialContext(ctx, unixSocketPath, - grpc.WithAuthority("localhost"), - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithBlock(), - grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, "unix", addr) - }), - ) - - if err != nil { - return nil, nil, fmt.Errorf(errFailedToDialDevicePlugin+" %v", err) - } - - return api.NewDevicePluginClient(c), c, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/handler.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/handler.go deleted file mode 100644 index 204afd3d1..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/handler.go +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - "fmt" - "os" - "time" - - core "k8s.io/api/core/v1" - "k8s.io/klog/v2" - api "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" -) - -func (s *server) GetPluginHandler() cache.PluginHandler { - if f, err := os.Create(s.socketDir + "DEPRECATION"); err != nil { - klog.ErrorS(err, "Failed to create deprecation file at socket dir", "path", s.socketDir) - } else { - f.Close() - klog.V(4).InfoS("Created deprecation file", "path", f.Name()) - } - return s -} - -func (s *server) RegisterPlugin(pluginName string, endpoint string, versions []string, pluginClientTimeout *time.Duration) error { - klog.V(2).InfoS("Registering plugin at endpoint", "plugin", pluginName, "endpoint", endpoint) - return s.connectClient(pluginName, endpoint) -} - -func (s *server) DeRegisterPlugin(pluginName, endpoint string) { - klog.V(2).InfoS("Deregistering plugin", "plugin", pluginName, "endpoint", endpoint) - client := s.getClient(pluginName) - if client != nil { - s.disconnectClient(pluginName, client) - } -} - -func (s *server) ValidatePlugin(pluginName string, endpoint string, versions []string) error { - klog.V(2).InfoS("Got plugin at endpoint with versions", "plugin", pluginName, "endpoint", endpoint, "versions", versions) - - if !s.isVersionCompatibleWithPlugin(versions...) { - return fmt.Errorf("manager version, %s, is not among plugin supported versions %v", api.Version, versions) - } - - if !v1helper.IsExtendedResourceName(core.ResourceName(pluginName)) { - return fmt.Errorf("invalid name of device plugin socket: %s", fmt.Sprintf(errInvalidResourceName, pluginName)) - } - - klog.V(2).InfoS("Device plugin validated", "plugin", pluginName, "endpoint", endpoint, "versions", versions) - return nil -} - -func (s *server) connectClient(name string, socketPath string) error { - c := NewPluginClient(name, socketPath, s.chandler) - - s.registerClient(name, c) - if err := c.Connect(); err != nil { - s.deregisterClient(name) - klog.ErrorS(err, "Failed to connect to new client", "resource", name) - return err - } - - klog.V(2).InfoS("Connected to new client", "resource", name) - go func() { - s.runClient(name, c) - }() - - return nil -} - -func (s *server) disconnectClient(name string, c Client) error { - s.deregisterClient(name) - return c.Disconnect() -} -func (s *server) registerClient(name string, c Client) { - s.mutex.Lock() - defer s.mutex.Unlock() - - s.clients[name] = c - klog.V(2).InfoS("Registered client", "name", name) -} - -func (s *server) deregisterClient(name string) { - s.mutex.Lock() - defer s.mutex.Unlock() - - delete(s.clients, name) - klog.V(2).InfoS("Deregistered client", "name", name) -} - -func (s *server) runClient(name string, c Client) { - c.Run() - - c = s.getClient(name) - if c == nil { - return - } - - if err := s.disconnectClient(name, c); err != nil { - klog.ErrorS(err, "Unable to disconnect client", "resource", name, "client", c) - } -} - -func (s *server) getClient(name string) Client { - s.mutex.Lock() - defer s.mutex.Unlock() - return s.clients[name] -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/server.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/server.go deleted file mode 100644 index e19e3efd2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/server.go +++ /dev/null @@ -1,226 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - "context" - "fmt" - "net" - "net/http" - "os" - "path/filepath" - "sync" - - "github.com/opencontainers/selinux/go-selinux" - "google.golang.org/grpc" - - core "k8s.io/api/core/v1" - "k8s.io/apiserver/pkg/server/healthz" - "k8s.io/klog/v2" - api "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - "k8s.io/kubernetes/pkg/kubelet/config" - "k8s.io/kubernetes/pkg/kubelet/metrics" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" -) - -// Server interface provides methods for Device plugin registration server. -type Server interface { - cache.PluginHandler - healthz.HealthChecker - Start() error - Stop() error - SocketPath() string -} - -type server struct { - socketName string - socketDir string - mutex sync.Mutex - wg sync.WaitGroup - grpc *grpc.Server - rhandler RegistrationHandler - chandler ClientHandler - clients map[string]Client - - // lastError records the last runtime error. A server is considered healthy till an actual error occurs. - lastError error -} - -// NewServer returns an initialized device plugin registration server. -func NewServer(socketPath string, rh RegistrationHandler, ch ClientHandler) (Server, error) { - if socketPath == "" || !filepath.IsAbs(socketPath) { - return nil, fmt.Errorf(errBadSocket+" %s", socketPath) - } - - dir, name := filepath.Split(socketPath) - - klog.V(2).InfoS("Creating device plugin registration server", "version", api.Version, "socket", socketPath) - s := &server{ - socketName: name, - socketDir: dir, - rhandler: rh, - chandler: ch, - clients: make(map[string]Client), - } - - return s, nil -} - -func (s *server) Start() error { - klog.V(2).InfoS("Starting device plugin registration server") - - if err := os.MkdirAll(s.socketDir, 0750); err != nil { - klog.ErrorS(err, "Failed to create the device plugin socket directory", "directory", s.socketDir) - return err - } - - if selinux.GetEnabled() { - if err := selinux.SetFileLabel(s.socketDir, config.KubeletPluginsDirSELinuxLabel); err != nil { - klog.ErrorS(err, "Unprivileged containerized plugins might not work. Could not set selinux context on socket dir", "path", s.socketDir) - } - } - - // For now, we leave cleanup of the *entire* directory up to the Handler - // (even though we should in theory be able to just wipe the whole directory) - // because the Handler stores its checkpoint file (amongst others) in here. - if err := s.rhandler.CleanupPluginDirectory(s.socketDir); err != nil { - klog.ErrorS(err, "Failed to cleanup the device plugin directory", "directory", s.socketDir) - return err - } - - ln, err := net.Listen("unix", s.SocketPath()) - if err != nil { - klog.ErrorS(err, "Failed to listen to socket while starting device plugin registry") - return err - } - - s.wg.Add(1) - s.grpc = grpc.NewServer([]grpc.ServerOption{}...) - - api.RegisterRegistrationServer(s.grpc, s) - go func() { - defer s.wg.Done() - s.setHealthy() - if err = s.grpc.Serve(ln); err != nil { - s.setUnhealthy(err) - klog.ErrorS(err, "Error while serving device plugin registration grpc server") - } - }() - - return nil -} - -func (s *server) Stop() error { - s.visitClients(func(r string, c Client) { - if err := s.disconnectClient(r, c); err != nil { - klog.ErrorS(err, "Failed to disconnect device plugin client", "resourceName", r) - } - }) - - s.mutex.Lock() - defer s.mutex.Unlock() - - if s.grpc == nil { - return nil - } - - s.grpc.Stop() - s.wg.Wait() - s.grpc = nil - // During kubelet termination, we do not need the registration server, - // and we consider the kubelet to be healthy even when it is down. - s.setHealthy() - klog.V(2).InfoS("Stopping device plugin registration server") - - return nil -} - -func (s *server) SocketPath() string { - return filepath.Join(s.socketDir, s.socketName) -} - -func (s *server) Register(ctx context.Context, r *api.RegisterRequest) (*api.Empty, error) { - klog.InfoS("Got registration request from device plugin with resource", "resourceName", r.ResourceName) - metrics.DevicePluginRegistrationCount.WithLabelValues(r.ResourceName).Inc() - - if !s.isVersionCompatibleWithPlugin(r.Version) { - err := fmt.Errorf(errUnsupportedVersion, r.Version, api.SupportedVersions) - klog.ErrorS(err, "Bad registration request from device plugin with resource", "resourceName", r.ResourceName) - return &api.Empty{}, err - } - - if !v1helper.IsExtendedResourceName(core.ResourceName(r.ResourceName)) { - err := fmt.Errorf(errInvalidResourceName, r.ResourceName) - klog.ErrorS(err, "Bad registration request from device plugin") - return &api.Empty{}, err - } - - if err := s.connectClient(r.ResourceName, filepath.Join(s.socketDir, r.Endpoint)); err != nil { - klog.ErrorS(err, "Error connecting to device plugin client") - return &api.Empty{}, err - } - - return &api.Empty{}, nil -} - -func (s *server) isVersionCompatibleWithPlugin(versions ...string) bool { - // TODO(vikasc): Currently this is fine as we only have a single supported version. When we do need to support - // multiple versions in the future, we may need to extend this function to return a supported version. - // E.g., say kubelet supports v1beta1 and v1beta2, and we get v1alpha1 and v1beta1 from a device plugin, - // this function should return v1beta1 - for _, version := range versions { - for _, supportedVersion := range api.SupportedVersions { - if version == supportedVersion { - return true - } - } - } - return false -} - -func (s *server) visitClients(visit func(r string, c Client)) { - s.mutex.Lock() - for r, c := range s.clients { - s.mutex.Unlock() - visit(r, c) - s.mutex.Lock() - } - s.mutex.Unlock() -} - -func (s *server) Name() string { - return "device-plugin" -} - -func (s *server) Check(_ *http.Request) error { - return s.lastError -} - -// setHealthy sets the health status of the gRPC server. -func (s *server) setHealthy() { - s.lastError = nil -} - -// setUnhealthy sets the health status of the gRPC server to unhealthy. -func (s *server) setUnhealthy(err error) { - if err == nil { - s.lastError = fmt.Errorf("device registration error: device plugin registration gRPC server failed and no device plugins can register") - return - } - s.lastError = fmt.Errorf("device registration error: device plugin registration gRPC server failed and no device plugins can register: %w", err) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/stub.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/stub.go deleted file mode 100644 index 9550d35e2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1/stub.go +++ /dev/null @@ -1,388 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1beta1 - -import ( - "context" - "net" - "os" - "path/filepath" - "sync" - "time" - - "github.com/fsnotify/fsnotify" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials/insecure" - - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/klog/v2" - pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" - watcherapi "k8s.io/kubelet/pkg/apis/pluginregistration/v1" -) - -// Stub implementation for DevicePlugin. -type Stub struct { - devs []*pluginapi.Device - socket string - resourceName string - preStartContainerFlag bool - getPreferredAllocationFlag bool - - stop chan interface{} - wg sync.WaitGroup - update chan []*pluginapi.Device - - server *grpc.Server - - // allocFunc is used for handling allocation request - allocFunc stubAllocFunc - - // getPreferredAllocFunc is used for handling getPreferredAllocation request - getPreferredAllocFunc stubGetPreferredAllocFunc - - // registerControlFunc is used for controlling auto-registration of requests - registerControlFunc stubRegisterControlFunc - - registrationStatus chan watcherapi.RegistrationStatus // for testing - endpoint string // for testing - - kubeletRestartWatcher *fsnotify.Watcher -} - -// stubGetPreferredAllocFunc is the function called when a getPreferredAllocation request is received from Kubelet -type stubGetPreferredAllocFunc func(r *pluginapi.PreferredAllocationRequest, devs map[string]pluginapi.Device) (*pluginapi.PreferredAllocationResponse, error) - -func defaultGetPreferredAllocFunc(r *pluginapi.PreferredAllocationRequest, devs map[string]pluginapi.Device) (*pluginapi.PreferredAllocationResponse, error) { - var response pluginapi.PreferredAllocationResponse - - return &response, nil -} - -// stubAllocFunc is the function called when an allocation request is received from Kubelet -type stubAllocFunc func(r *pluginapi.AllocateRequest, devs map[string]pluginapi.Device) (*pluginapi.AllocateResponse, error) - -func defaultAllocFunc(r *pluginapi.AllocateRequest, devs map[string]pluginapi.Device) (*pluginapi.AllocateResponse, error) { - var response pluginapi.AllocateResponse - - return &response, nil -} - -// stubRegisterControlFunc is the function called when a registration request is received from Kubelet -type stubRegisterControlFunc func() bool - -func defaultRegisterControlFunc() bool { - return true -} - -// NewDevicePluginStub returns an initialized DevicePlugin Stub. -func NewDevicePluginStub(devs []*pluginapi.Device, socket string, name string, preStartContainerFlag bool, getPreferredAllocationFlag bool) *Stub { - - watcher, err := fsnotify.NewWatcher() - if err != nil { - klog.ErrorS(err, "Watcher creation failed") - panic(err) - } - - return &Stub{ - devs: devs, - socket: socket, - resourceName: name, - preStartContainerFlag: preStartContainerFlag, - getPreferredAllocationFlag: getPreferredAllocationFlag, - registerControlFunc: defaultRegisterControlFunc, - - stop: make(chan interface{}), - update: make(chan []*pluginapi.Device), - - allocFunc: defaultAllocFunc, - getPreferredAllocFunc: defaultGetPreferredAllocFunc, - kubeletRestartWatcher: watcher, - } -} - -// SetGetPreferredAllocFunc sets allocFunc of the device plugin -func (m *Stub) SetGetPreferredAllocFunc(f stubGetPreferredAllocFunc) { - m.getPreferredAllocFunc = f -} - -// SetAllocFunc sets allocFunc of the device plugin -func (m *Stub) SetAllocFunc(f stubAllocFunc) { - m.allocFunc = f -} - -// SetRegisterControlFunc sets RegisterControlFunc of the device plugin -func (m *Stub) SetRegisterControlFunc(f stubRegisterControlFunc) { - m.registerControlFunc = f -} - -// Start starts the gRPC server of the device plugin. Can only -// be called once. -func (m *Stub) Start() error { - klog.InfoS("Starting device plugin server") - err := m.cleanup() - if err != nil { - return err - } - - sock, err := net.Listen("unix", m.socket) - if err != nil { - return err - } - - m.wg.Add(1) - m.server = grpc.NewServer([]grpc.ServerOption{}...) - pluginapi.RegisterDevicePluginServer(m.server, m) - watcherapi.RegisterRegistrationServer(m.server, m) - - err = m.kubeletRestartWatcher.Add(filepath.Dir(m.socket)) - if err != nil { - klog.ErrorS(err, "Failed to add watch", "devicePluginPath", pluginapi.DevicePluginPath) - return err - } - - go func() { - defer m.wg.Done() - if err = m.server.Serve(sock); err != nil { - klog.ErrorS(err, "Error while serving device plugin registration grpc server") - } - }() - - var lastDialErr error - wait.PollImmediate(1*time.Second, 10*time.Second, func() (bool, error) { - var conn *grpc.ClientConn - _, conn, lastDialErr = dial(m.socket) - if lastDialErr != nil { - return false, nil - } - conn.Close() - return true, nil - }) - if lastDialErr != nil { - return lastDialErr - } - - klog.InfoS("Starting to serve on socket", "socket", m.socket) - return nil -} - -func (m *Stub) Restart() error { - klog.InfoS("Restarting Device Plugin server") - if m.server == nil { - return nil - } - - m.server.Stop() - m.server = nil - - return m.Start() -} - -// Stop stops the gRPC server. Can be called without a prior Start -// and more than once. Not safe to be called concurrently by different -// goroutines! -func (m *Stub) Stop() error { - klog.InfoS("Stopping device plugin server") - if m.server == nil { - return nil - } - - m.kubeletRestartWatcher.Close() - - m.server.Stop() - m.wg.Wait() - m.server = nil - close(m.stop) // This prevents re-starting the server. - - return m.cleanup() -} - -func (m *Stub) Watch(kubeletEndpoint, resourceName, pluginSockDir string) { - for { - select { - // Detect a kubelet restart by watching for a newly created - // 'pluginapi.KubeletSocket' file. When this occurs, restart - // the device plugin server - case event := <-m.kubeletRestartWatcher.Events: - if event.Name == kubeletEndpoint && event.Op&fsnotify.Create == fsnotify.Create { - klog.InfoS("inotify: file created, restarting", "kubeletEndpoint", kubeletEndpoint) - var lastErr error - - err := wait.PollUntilContextTimeout(context.Background(), 10*time.Second, 2*time.Minute, false, func(context.Context) (done bool, err error) { - restartErr := m.Restart() - if restartErr == nil { - return true, nil - } - klog.ErrorS(restartErr, "Retrying after error") - lastErr = restartErr - return false, nil - }) - if err != nil { - klog.ErrorS(err, "Unable to restart server: wait timed out", "lastErr", lastErr.Error()) - panic(err) - } - - if ok := m.registerControlFunc(); ok { - if err := m.Register(kubeletEndpoint, resourceName, pluginSockDir); err != nil { - klog.ErrorS(err, "Unable to register to kubelet") - panic(err) - } - } - } - - // Watch for any other fs errors and log them. - case err := <-m.kubeletRestartWatcher.Errors: - klog.ErrorS(err, "inotify error") - } - } -} - -// GetInfo is the RPC which return pluginInfo -func (m *Stub) GetInfo(ctx context.Context, req *watcherapi.InfoRequest) (*watcherapi.PluginInfo, error) { - klog.InfoS("GetInfo") - return &watcherapi.PluginInfo{ - Type: watcherapi.DevicePlugin, - Name: m.resourceName, - Endpoint: m.endpoint, - SupportedVersions: []string{pluginapi.Version}}, nil -} - -// NotifyRegistrationStatus receives the registration notification from watcher -func (m *Stub) NotifyRegistrationStatus(ctx context.Context, status *watcherapi.RegistrationStatus) (*watcherapi.RegistrationStatusResponse, error) { - if m.registrationStatus != nil { - m.registrationStatus <- *status - } - if !status.PluginRegistered { - klog.InfoS("Registration failed", "err", status.Error) - } - return &watcherapi.RegistrationStatusResponse{}, nil -} - -// Register registers the device plugin for the given resourceName with Kubelet. -func (m *Stub) Register(kubeletEndpoint, resourceName string, pluginSockDir string) error { - klog.InfoS("Register", "kubeletEndpoint", kubeletEndpoint, "resourceName", resourceName, "socket", pluginSockDir) - - if pluginSockDir != "" { - if _, err := os.Stat(pluginSockDir + "DEPRECATION"); err == nil { - klog.InfoS("Deprecation file found. Skip registration") - return nil - } - } - klog.InfoS("Deprecation file not found. Invoke registration") - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - conn, err := grpc.DialContext(ctx, kubeletEndpoint, - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithBlock(), - grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, "unix", addr) - })) - if err != nil { - return err - } - defer conn.Close() - client := pluginapi.NewRegistrationClient(conn) - reqt := &pluginapi.RegisterRequest{ - Version: pluginapi.Version, - Endpoint: filepath.Base(m.socket), - ResourceName: resourceName, - Options: &pluginapi.DevicePluginOptions{ - PreStartRequired: m.preStartContainerFlag, - GetPreferredAllocationAvailable: m.getPreferredAllocationFlag, - }, - } - - _, err = client.Register(context.Background(), reqt) - if err != nil { - // Stop server - m.server.Stop() - klog.ErrorS(err, "Client unable to register to kubelet") - return err - } - klog.InfoS("Device Plugin registered with the Kubelet") - return err -} - -// GetDevicePluginOptions returns DevicePluginOptions settings for the device plugin. -func (m *Stub) GetDevicePluginOptions(ctx context.Context, e *pluginapi.Empty) (*pluginapi.DevicePluginOptions, error) { - options := &pluginapi.DevicePluginOptions{ - PreStartRequired: m.preStartContainerFlag, - GetPreferredAllocationAvailable: m.getPreferredAllocationFlag, - } - return options, nil -} - -// PreStartContainer resets the devices received -func (m *Stub) PreStartContainer(ctx context.Context, r *pluginapi.PreStartContainerRequest) (*pluginapi.PreStartContainerResponse, error) { - klog.InfoS("PreStartContainer", "request", r) - return &pluginapi.PreStartContainerResponse{}, nil -} - -// ListAndWatch lists devices and update that list according to the Update call -func (m *Stub) ListAndWatch(e *pluginapi.Empty, s pluginapi.DevicePlugin_ListAndWatchServer) error { - klog.InfoS("ListAndWatch") - - s.Send(&pluginapi.ListAndWatchResponse{Devices: m.devs}) - - for { - select { - case <-m.stop: - return nil - case updated := <-m.update: - s.Send(&pluginapi.ListAndWatchResponse{Devices: updated}) - } - } -} - -// Update allows the device plugin to send new devices through ListAndWatch -func (m *Stub) Update(devs []*pluginapi.Device) { - m.update <- devs -} - -// GetPreferredAllocation gets the preferred allocation from a set of available devices -func (m *Stub) GetPreferredAllocation(ctx context.Context, r *pluginapi.PreferredAllocationRequest) (*pluginapi.PreferredAllocationResponse, error) { - klog.InfoS("GetPreferredAllocation", "request", r) - - devs := make(map[string]pluginapi.Device) - - for _, dev := range m.devs { - devs[dev.ID] = *dev - } - - return m.getPreferredAllocFunc(r, devs) -} - -// Allocate does a mock allocation -func (m *Stub) Allocate(ctx context.Context, r *pluginapi.AllocateRequest) (*pluginapi.AllocateResponse, error) { - klog.InfoS("Allocate", "request", r) - - devs := make(map[string]pluginapi.Device) - - for _, dev := range m.devs { - devs[dev.ID] = *dev - } - - return m.allocFunc(r, devs) -} - -func (m *Stub) cleanup() error { - if err := os.Remove(m.socket); err != nil && !os.IsNotExist(err) { - return err - } - - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/pod_devices.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/pod_devices.go deleted file mode 100644 index 806ab3c61..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/pod_devices.go +++ /dev/null @@ -1,454 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package devicemanager - -import ( - "maps" - "sync" - - "k8s.io/klog/v2" - - "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" - pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" - kubefeatures "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" -) - -type deviceAllocateInfo struct { - // deviceIds contains device Ids allocated to this container for the given resourceName. - deviceIds checkpoint.DevicesPerNUMA - // allocResp contains cached rpc AllocateResponse. - allocResp *pluginapi.ContainerAllocateResponse -} - -type resourceAllocateInfo map[string]deviceAllocateInfo // Keyed by resourceName. -type containerDevices map[string]resourceAllocateInfo // Keyed by containerName. -type podDevices struct { - sync.RWMutex - devs map[string]containerDevices // Keyed by podUID. -} - -// NewPodDevices is a function that returns object of podDevices type with its own guard -// RWMutex and a map where key is a pod UID and value contains -// container devices information of type containerDevices. -func newPodDevices() *podDevices { - return &podDevices{devs: make(map[string]containerDevices)} -} - -func (pdev *podDevices) pods() sets.Set[string] { - pdev.RLock() - defer pdev.RUnlock() - ret := sets.New[string]() - for k := range pdev.devs { - ret.Insert(k) - } - return ret -} - -func (pdev *podDevices) size() int { - pdev.RLock() - defer pdev.RUnlock() - return len(pdev.devs) -} - -func (pdev *podDevices) hasPod(podUID string) bool { - pdev.RLock() - defer pdev.RUnlock() - _, podExists := pdev.devs[podUID] - return podExists -} - -func (pdev *podDevices) insert(podUID, contName, resource string, devices checkpoint.DevicesPerNUMA, resp *pluginapi.ContainerAllocateResponse) { - pdev.Lock() - defer pdev.Unlock() - if _, podExists := pdev.devs[podUID]; !podExists { - pdev.devs[podUID] = make(containerDevices) - } - if _, contExists := pdev.devs[podUID][contName]; !contExists { - pdev.devs[podUID][contName] = make(resourceAllocateInfo) - } - pdev.devs[podUID][contName][resource] = deviceAllocateInfo{ - deviceIds: devices, - allocResp: resp, - } -} - -func (pdev *podDevices) delete(pods []string) { - pdev.Lock() - defer pdev.Unlock() - for _, uid := range pods { - delete(pdev.devs, uid) - } -} - -// Returns list of device Ids allocated to the given pod for the given resource. -// Returns nil if we don't have cached state for the given . -func (pdev *podDevices) podDevices(podUID, resource string) sets.Set[string] { - pdev.RLock() - defer pdev.RUnlock() - - ret := sets.New[string]() - for contName := range pdev.devs[podUID] { - ret = ret.Union(pdev.containerDevices(podUID, contName, resource)) - } - return ret -} - -// Returns list of device Ids allocated to the given container for the given resource. -// Returns nil if we don't have cached state for the given . -func (pdev *podDevices) containerDevices(podUID, contName, resource string) sets.Set[string] { - pdev.RLock() - defer pdev.RUnlock() - if _, podExists := pdev.devs[podUID]; !podExists { - return nil - } - if _, contExists := pdev.devs[podUID][contName]; !contExists { - return nil - } - devs, resourceExists := pdev.devs[podUID][contName][resource] - if !resourceExists { - return nil - } - return devs.deviceIds.Devices() -} - -// Populates allocatedResources with the device resources allocated to the specified . -func (pdev *podDevices) addContainerAllocatedResources(podUID, contName string, allocatedResources map[string]sets.Set[string]) { - pdev.RLock() - defer pdev.RUnlock() - containers, exists := pdev.devs[podUID] - if !exists { - return - } - resources, exists := containers[contName] - if !exists { - return - } - for resource, devices := range resources { - allocatedResources[resource] = allocatedResources[resource].Union(devices.deviceIds.Devices()) - } -} - -// Removes the device resources allocated to the specified from allocatedResources. -func (pdev *podDevices) removeContainerAllocatedResources(podUID, contName string, allocatedResources map[string]sets.Set[string]) { - pdev.RLock() - defer pdev.RUnlock() - containers, exists := pdev.devs[podUID] - if !exists { - return - } - resources, exists := containers[contName] - if !exists { - return - } - for resource, devices := range resources { - allocatedResources[resource] = allocatedResources[resource].Difference(devices.deviceIds.Devices()) - } -} - -// Returns all devices allocated to the pods being tracked, keyed by resourceName. -func (pdev *podDevices) devices() map[string]sets.Set[string] { - ret := make(map[string]sets.Set[string]) - pdev.RLock() - defer pdev.RUnlock() - for _, containerDevices := range pdev.devs { - for _, resources := range containerDevices { - for resource, devices := range resources { - if _, exists := ret[resource]; !exists { - ret[resource] = sets.New[string]() - } - if devices.allocResp != nil { - ret[resource] = ret[resource].Union(devices.deviceIds.Devices()) - } - } - } - } - return ret -} - -// Returns podUID and containerName for a device -func (pdev *podDevices) getPodAndContainerForDevice(deviceID string) (string, string) { - pdev.RLock() - defer pdev.RUnlock() - for podUID, containerDevices := range pdev.devs { - for containerName, resources := range containerDevices { - for _, devices := range resources { - if devices.deviceIds.Devices().Has(deviceID) { - return podUID, containerName - } - } - } - } - return "", "" -} - -// Turns podDevices to checkpointData. -func (pdev *podDevices) toCheckpointData() []checkpoint.PodDevicesEntry { - var data []checkpoint.PodDevicesEntry - pdev.RLock() - defer pdev.RUnlock() - for podUID, containerDevices := range pdev.devs { - for conName, resources := range containerDevices { - for resource, devices := range resources { - if devices.allocResp == nil { - klog.ErrorS(nil, "Can't marshal allocResp, allocation response is missing", "podUID", podUID, "containerName", conName, "resourceName", resource) - continue - } - - allocResp, err := devices.allocResp.Marshal() - if err != nil { - klog.ErrorS(err, "Can't marshal allocResp", "podUID", podUID, "containerName", conName, "resourceName", resource) - continue - } - data = append(data, checkpoint.PodDevicesEntry{ - PodUID: podUID, - ContainerName: conName, - ResourceName: resource, - DeviceIDs: devices.deviceIds, - AllocResp: allocResp}) - } - } - } - return data -} - -// Populates podDevices from the passed in checkpointData. -func (pdev *podDevices) fromCheckpointData(data []checkpoint.PodDevicesEntry) { - for _, entry := range data { - klog.V(2).InfoS("Get checkpoint entry", - "podUID", entry.PodUID, "containerName", entry.ContainerName, - "resourceName", entry.ResourceName, "deviceIDs", entry.DeviceIDs, "allocated", entry.AllocResp) - allocResp := &pluginapi.ContainerAllocateResponse{} - err := allocResp.Unmarshal(entry.AllocResp) - if err != nil { - klog.ErrorS(err, "Can't unmarshal allocResp", "podUID", entry.PodUID, "containerName", entry.ContainerName, "resourceName", entry.ResourceName) - continue - } - pdev.insert(entry.PodUID, entry.ContainerName, entry.ResourceName, entry.DeviceIDs, allocResp) - } -} - -// Returns combined container runtime settings to consume the container's allocated devices. -func (pdev *podDevices) deviceRunContainerOptions(podUID, contName string) *DeviceRunContainerOptions { - pdev.RLock() - defer pdev.RUnlock() - - containers, exists := pdev.devs[podUID] - if !exists { - return nil - } - resources, exists := containers[contName] - if !exists { - return nil - } - opts := &DeviceRunContainerOptions{} - // Maps to detect duplicate settings. - devsMap := make(map[string]string) - mountsMap := make(map[string]string) - envsMap := make(map[string]string) - annotationsMap := make(map[string]string) - // Keep track of all CDI devices requested for the container. - allCDIDevices := sets.New[string]() - // Loops through AllocationResponses of all cached device resources. - for _, devices := range resources { - resp := devices.allocResp - // Each Allocate response has the following artifacts. - // Environment variables - // Mount points - // Device files - // Container annotations - // CDI device IDs - // These artifacts are per resource per container. - // Updates RunContainerOptions.Envs. - for k, v := range resp.Envs { - if e, ok := envsMap[k]; ok { - klog.V(4).InfoS("Skip existing env", "envKey", k, "envValue", v) - if e != v { - klog.ErrorS(nil, "Environment variable has conflicting setting", "envKey", k, "expected", v, "got", e) - } - continue - } - klog.V(4).InfoS("Add env", "envKey", k, "envValue", v) - envsMap[k] = v - opts.Envs = append(opts.Envs, kubecontainer.EnvVar{Name: k, Value: v}) - } - - // Updates RunContainerOptions.Devices. - for _, dev := range resp.Devices { - if d, ok := devsMap[dev.ContainerPath]; ok { - klog.V(4).InfoS("Skip existing device", "containerPath", dev.ContainerPath, "hostPath", dev.HostPath) - if d != dev.HostPath { - klog.ErrorS(nil, "Container device has conflicting mapping host devices", - "containerPath", dev.ContainerPath, "got", d, "expected", dev.HostPath) - } - continue - } - klog.V(4).InfoS("Add device", "containerPath", dev.ContainerPath, "hostPath", dev.HostPath) - devsMap[dev.ContainerPath] = dev.HostPath - opts.Devices = append(opts.Devices, kubecontainer.DeviceInfo{ - PathOnHost: dev.HostPath, - PathInContainer: dev.ContainerPath, - Permissions: dev.Permissions, - }) - } - - // Updates RunContainerOptions.Mounts. - for _, mount := range resp.Mounts { - if m, ok := mountsMap[mount.ContainerPath]; ok { - klog.V(4).InfoS("Skip existing mount", "containerPath", mount.ContainerPath, "hostPath", mount.HostPath) - if m != mount.HostPath { - klog.ErrorS(nil, "Container mount has conflicting mapping host mounts", - "containerPath", mount.ContainerPath, "conflictingPath", m, "hostPath", mount.HostPath) - } - continue - } - klog.V(4).InfoS("Add mount", "containerPath", mount.ContainerPath, "hostPath", mount.HostPath) - mountsMap[mount.ContainerPath] = mount.HostPath - opts.Mounts = append(opts.Mounts, kubecontainer.Mount{ - Name: mount.ContainerPath, - ContainerPath: mount.ContainerPath, - HostPath: mount.HostPath, - ReadOnly: mount.ReadOnly, - // TODO: This may need to be part of Device plugin API. - SELinuxRelabel: false, - }) - } - - // Updates for Annotations - for k, v := range resp.Annotations { - if e, ok := annotationsMap[k]; ok { - klog.V(4).InfoS("Skip existing annotation", "annotationKey", k, "annotationValue", v) - if e != v { - klog.ErrorS(nil, "Annotation has conflicting setting", "annotationKey", k, "expected", e, "got", v) - } - continue - } - klog.V(4).InfoS("Add annotation", "annotationKey", k, "annotationValue", v) - annotationsMap[k] = v - opts.Annotations = append(opts.Annotations, kubecontainer.Annotation{Name: k, Value: v}) - } - - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DevicePluginCDIDevices) { - // Updates for CDI devices. - cdiDevices := getCDIDeviceInfo(resp, allCDIDevices) - opts.CDIDevices = append(opts.CDIDevices, cdiDevices...) - } - } - - return opts -} - -// getCDIDeviceInfo returns CDI devices from an allocate response -func getCDIDeviceInfo(resp *pluginapi.ContainerAllocateResponse, knownCDIDevices sets.Set[string]) []kubecontainer.CDIDevice { - var cdiDevices []kubecontainer.CDIDevice - for _, cdiDevice := range resp.CDIDevices { - if knownCDIDevices.Has(cdiDevice.Name) { - klog.V(4).InfoS("Skip existing CDI Device", "name", cdiDevice.Name) - continue - } - klog.V(4).InfoS("Add CDI device", "name", cdiDevice.Name) - knownCDIDevices.Insert(cdiDevice.Name) - - device := kubecontainer.CDIDevice{ - Name: cdiDevice.Name, - } - cdiDevices = append(cdiDevices, device) - } - - return cdiDevices -} - -// getContainerDevices returns the devices assigned to the provided container for all ResourceNames -func (pdev *podDevices) getContainerDevices(podUID, contName string) ResourceDeviceInstances { - pdev.RLock() - defer pdev.RUnlock() - - if _, podExists := pdev.devs[podUID]; !podExists { - return nil - } - if _, contExists := pdev.devs[podUID][contName]; !contExists { - return nil - } - resDev := NewResourceDeviceInstances() - for resource, allocateInfo := range pdev.devs[podUID][contName] { - if len(allocateInfo.deviceIds) == 0 { - continue - } - devicePluginMap := make(map[string]pluginapi.Device) - for numaid, devlist := range allocateInfo.deviceIds { - for _, devID := range devlist { - var topology *pluginapi.TopologyInfo - if numaid != nodeWithoutTopology { - NUMANodes := []*pluginapi.NUMANode{{ID: numaid}} - if pDev, ok := devicePluginMap[devID]; ok && pDev.Topology != nil { - if nodes := pDev.Topology.GetNodes(); nodes != nil { - NUMANodes = append(NUMANodes, nodes...) - } - } - - // ID and Healthy are not relevant here. - topology = &pluginapi.TopologyInfo{Nodes: NUMANodes} - } - devicePluginMap[devID] = pluginapi.Device{ - Topology: topology, - } - } - } - resDev[resource] = devicePluginMap - } - return resDev -} - -// DeviceInstances is a mapping device name -> plugin device data -type DeviceInstances map[string]pluginapi.Device - -// ResourceDeviceInstances is a mapping resource name -> DeviceInstances -type ResourceDeviceInstances map[string]DeviceInstances - -// NewResourceDeviceInstances returns a new ResourceDeviceInstances -func NewResourceDeviceInstances() ResourceDeviceInstances { - return make(ResourceDeviceInstances) -} - -// Clone returns a clone of ResourceDeviceInstances -func (rdev ResourceDeviceInstances) Clone() ResourceDeviceInstances { - clone := NewResourceDeviceInstances() - for resourceName, resourceDevs := range rdev { - clone[resourceName] = maps.Clone(resourceDevs) - } - return clone -} - -// Filter takes a condition set expressed as map[string]sets.Set[string] and returns a new -// ResourceDeviceInstances with only the devices matching the condition set. -func (rdev ResourceDeviceInstances) Filter(cond map[string]sets.Set[string]) ResourceDeviceInstances { - filtered := NewResourceDeviceInstances() - for resourceName, filterIDs := range cond { - if _, exists := rdev[resourceName]; !exists { - continue - } - filtered[resourceName] = DeviceInstances{} - for instanceID, instance := range rdev[resourceName] { - if filterIDs.Has(instanceID) { - filtered[resourceName][instanceID] = instance - } - } - } - return filtered -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go deleted file mode 100644 index f4d7fa73a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/topology_hints.go +++ /dev/null @@ -1,252 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package devicemanager - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/component-helpers/resource" - "k8s.io/klog/v2" - pluginapi "k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1" - - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" -) - -// GetTopologyHints implements the TopologyManager HintProvider Interface which -// ensures the Device Manager is consulted when Topology Aware Hints for each -// container are created. -func (m *ManagerImpl) GetTopologyHints(pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - // Garbage collect any stranded device resources before providing TopologyHints - m.UpdateAllocatedDevices() - - // Loop through all device resources and generate TopologyHints for them. - deviceHints := make(map[string][]topologymanager.TopologyHint) - accumulatedResourceRequests := m.getContainerDeviceRequest(container) - - m.mutex.Lock() - defer m.mutex.Unlock() - for resource, requested := range accumulatedResourceRequests { - // Only consider devices that actually contain topology information. - if aligned := m.deviceHasTopologyAlignment(resource); !aligned { - klog.InfoS("Resource does not have a topology preference", "resourceName", resource, "pod", klog.KObj(pod), "containerName", container.Name, "request", requested) - deviceHints[resource] = nil - continue - } - - // Short circuit to regenerate the same hints if there are already - // devices allocated to the Container. This might happen after a - // kubelet restart, for example. - allocated := m.podDevices.containerDevices(string(pod.UID), container.Name, resource) - if allocated.Len() > 0 { - if allocated.Len() != requested { - klog.InfoS("Resource already allocated to pod with different number than request", "resourceName", resource, "pod", klog.KObj(pod), "containerName", container.Name, "request", requested, "allocated", allocated.Len()) - deviceHints[resource] = []topologymanager.TopologyHint{} - continue - } - klog.InfoS("Regenerating TopologyHints for resource already allocated to pod", "resourceName", resource, "pod", klog.KObj(pod), "containerName", container.Name) - deviceHints[resource] = m.generateDeviceTopologyHints(resource, allocated, sets.Set[string]{}, requested) - continue - } - - // Get the list of available devices, for which TopologyHints should be generated. - available := m.getAvailableDevices(resource) - reusable := m.devicesToReuse[string(pod.UID)][resource] - if available.Union(reusable).Len() < requested { - klog.InfoS("Unable to generate topology hints: requested number of devices unavailable", "resourceName", resource, "pod", klog.KObj(pod), "containerName", container.Name, "request", requested, "available", available.Union(reusable).Len()) - deviceHints[resource] = []topologymanager.TopologyHint{} - continue - } - - // Generate TopologyHints for this resource given the current - // request size and the list of available devices. - deviceHints[resource] = m.generateDeviceTopologyHints(resource, available, reusable, requested) - } - - return deviceHints -} - -// GetPodTopologyHints implements the topologymanager.HintProvider Interface which -// ensures the Device Manager is consulted when Topology Aware Hints for Pod are created. -func (m *ManagerImpl) GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint { - // Garbage collect any stranded device resources before providing TopologyHints - m.UpdateAllocatedDevices() - - deviceHints := make(map[string][]topologymanager.TopologyHint) - accumulatedResourceRequests := m.getPodDeviceRequest(pod) - - m.mutex.Lock() - defer m.mutex.Unlock() - for resource, requested := range accumulatedResourceRequests { - // Only consider devices that actually contain topology information. - if aligned := m.deviceHasTopologyAlignment(resource); !aligned { - klog.InfoS("Resource does not have a topology preference", "resourceName", resource, "pod", klog.KObj(pod), "request", requested) - deviceHints[resource] = nil - continue - } - - // Short circuit to regenerate the same hints if there are already - // devices allocated to the Pod. This might happen after a - // kubelet restart, for example. - allocated := m.podDevices.podDevices(string(pod.UID), resource) - if allocated.Len() > 0 { - if allocated.Len() != requested { - klog.InfoS("Resource already allocated to pod with different number than request", "resourceName", resource, "pod", klog.KObj(pod), "request", requested, "allocated", allocated.Len()) - deviceHints[resource] = []topologymanager.TopologyHint{} - continue - } - klog.InfoS("Regenerating TopologyHints for resource already allocated to pod", "resourceName", resource, "pod", klog.KObj(pod), "allocated", allocated.Len()) - deviceHints[resource] = m.generateDeviceTopologyHints(resource, allocated, sets.Set[string]{}, requested) - continue - } - - // Get the list of available devices, for which TopologyHints should be generated. - available := m.getAvailableDevices(resource) - if available.Len() < requested { - klog.InfoS("Unable to generate topology hints: requested number of devices unavailable", "resourceName", resource, "pod", klog.KObj(pod), "request", requested, "available", available.Len()) - deviceHints[resource] = []topologymanager.TopologyHint{} - continue - } - - // Generate TopologyHints for this resource given the current - // request size and the list of available devices. - deviceHints[resource] = m.generateDeviceTopologyHints(resource, available, sets.Set[string]{}, requested) - } - - return deviceHints -} - -func (m *ManagerImpl) deviceHasTopologyAlignment(resource string) bool { - // If any device has Topology NUMANodes available, we assume they care about alignment. - for _, device := range m.allDevices[resource] { - if device.Topology != nil && len(device.Topology.Nodes) > 0 { - return true - } - } - return false -} - -func (m *ManagerImpl) getAvailableDevices(resource string) sets.Set[string] { - // Strip all devices in use from the list of healthy ones. - return m.healthyDevices[resource].Difference(m.allocatedDevices[resource]) -} - -func (m *ManagerImpl) generateDeviceTopologyHints(resource string, available sets.Set[string], reusable sets.Set[string], request int) []topologymanager.TopologyHint { - // Initialize minAffinitySize to include all NUMA Nodes - minAffinitySize := len(m.numaNodes) - - // Iterate through all combinations of NUMA Nodes and build hints from them. - hints := []topologymanager.TopologyHint{} - bitmask.IterateBitMasks(m.numaNodes, func(mask bitmask.BitMask) { - // First, update minAffinitySize for the current request size. - devicesInMask := 0 - for _, device := range m.allDevices[resource] { - if mask.AnySet(m.getNUMANodeIds(device.Topology)) { - devicesInMask++ - } - } - if devicesInMask >= request && mask.Count() < minAffinitySize { - minAffinitySize = mask.Count() - } - - // Then check to see if all the reusable devices are part of the bitmask. - numMatching := 0 - for d := range reusable { - // Skip the device if it doesn't specify any topology info. - if m.allDevices[resource][d].Topology == nil { - continue - } - // Otherwise disregard this mask if its NUMANode isn't part of it. - if !mask.AnySet(m.getNUMANodeIds(m.allDevices[resource][d].Topology)) { - return - } - numMatching++ - } - - // Finally, check to see if enough available devices remain on the - // current NUMA node combination to satisfy the device request. - for d := range available { - if mask.AnySet(m.getNUMANodeIds(m.allDevices[resource][d].Topology)) { - numMatching++ - } - } - - // If they don't, then move onto the next combination. - if numMatching < request { - return - } - - // Otherwise, create a new hint from the NUMA mask and add it to the - // list of hints. We set all hint preferences to 'false' on the first - // pass through. - hints = append(hints, topologymanager.TopologyHint{ - NUMANodeAffinity: mask, - Preferred: false, - }) - }) - - // Loop back through all hints and update the 'Preferred' field based on - // counting the number of bits sets in the affinity mask and comparing it - // to the minAffinity. Only those with an equal number of bits set will be - // considered preferred. - for i := range hints { - if hints[i].NUMANodeAffinity.Count() == minAffinitySize { - hints[i].Preferred = true - } - } - - return hints -} - -func (m *ManagerImpl) getNUMANodeIds(topology *pluginapi.TopologyInfo) []int { - if topology == nil { - return nil - } - var ids []int - for _, n := range topology.Nodes { - ids = append(ids, int(n.ID)) - } - return ids -} - -func (m *ManagerImpl) getPodDeviceRequest(pod *v1.Pod) map[string]int { - // for these device plugin resources, requests == limits - limits := resource.PodLimits(pod, resource.PodResourcesOptions{ - ExcludeOverhead: true, - }) - podRequests := make(map[string]int) - for resourceName, quantity := range limits { - if !m.isDevicePluginResource(string(resourceName)) { - continue - } - podRequests[string(resourceName)] = int(quantity.Value()) - } - return podRequests -} - -func (m *ManagerImpl) getContainerDeviceRequest(container *v1.Container) map[string]int { - containerRequests := make(map[string]int) - for resourceObj, requestedObj := range container.Resources.Limits { - resource := string(resourceObj) - requested := int(requestedObj.Value()) - if !m.isDevicePluginResource(resource) { - continue - } - containerRequests[resource] = requested - } - return containerRequests -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go deleted file mode 100644 index bdf0b27d6..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/types.go +++ /dev/null @@ -1,123 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package devicemanager - -import ( - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apiserver/pkg/server/healthz" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/config" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" - schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// Manager manages all the Device Plugins running on a node. -type Manager interface { - // Start starts device plugin registration service. - Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, initialContainers containermap.ContainerMap, initialContainerRunningSet sets.Set[string]) error - - // Allocate configures and assigns devices to a container in a pod. From - // the requested device resources, Allocate will communicate with the - // owning device plugin to allow setup procedures to take place, and for - // the device plugin to provide runtime settings to use the device - // (environment variables, mount points and device files). - Allocate(pod *v1.Pod, container *v1.Container) error - - // UpdatePluginResources updates node resources based on devices already - // allocated to pods. The node object is provided for the device manager to - // update the node capacity to reflect the currently available devices. - UpdatePluginResources(node *schedulerframework.NodeInfo, attrs *lifecycle.PodAdmitAttributes) error - - // Stop stops the manager. - Stop() error - - // GetDeviceRunContainerOptions checks whether we have cached containerDevices - // for the passed-in and returns its DeviceRunContainerOptions - // for the found one. An empty struct is returned in case no cached state is found. - GetDeviceRunContainerOptions(pod *v1.Pod, container *v1.Container) (*DeviceRunContainerOptions, error) - - // GetCapacity returns the amount of available device plugin resource capacity, resource allocatable - // and inactive device plugin resources previously registered on the node. - GetCapacity() (v1.ResourceList, v1.ResourceList, []string) - - // GetWatcherHandler returns the plugin handler for the device manager. - GetWatcherHandler() cache.PluginHandler - GetHealthChecker() healthz.HealthChecker - - // GetDevices returns information about the devices assigned to pods and containers - GetDevices(podUID, containerName string) ResourceDeviceInstances - - // UpdateAllocatedResourcesStatus updates the status of allocated resources for the pod. - UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStatus) - - // GetAllocatableDevices returns information about all the devices known to the manager - GetAllocatableDevices() ResourceDeviceInstances - - // ShouldResetExtendedResourceCapacity returns whether the extended resources should be reset or not, - // depending on the checkpoint file availability. Absence of the checkpoint file strongly indicates - // the node has been recreated. - ShouldResetExtendedResourceCapacity() bool - - // TopologyManager HintProvider provider indicates the Device Manager implements the Topology Manager Interface - // and is consulted to make Topology aware resource alignments - GetTopologyHints(pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint - - // TopologyManager HintProvider provider indicates the Device Manager implements the Topology Manager Interface - // and is consulted to make Topology aware resource alignments per Pod - GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint - - // UpdateAllocatedDevices frees any Devices that are bound to terminated pods. - UpdateAllocatedDevices() - - // Updates returns a channel that receives an Update when the device changed its status. - Updates() <-chan resourceupdates.Update -} - -// DeviceRunContainerOptions contains the combined container runtime settings to consume its allocated devices. -type DeviceRunContainerOptions struct { - // The environment variables list. - Envs []kubecontainer.EnvVar - // The mounts for the container. - Mounts []kubecontainer.Mount - // The host devices mapped into the container. - Devices []kubecontainer.DeviceInfo - // The Annotations for the container - Annotations []kubecontainer.Annotation - // CDI Devices for the container - CDIDevices []kubecontainer.CDIDevice -} - -// TODO: evaluate whether we need this error definition. -const ( - errEndpointStopped = "endpoint %v has been stopped" -) - -// endpointStopGracePeriod indicates the grace period after an endpoint is stopped -// because its device plugin fails. DeviceManager keeps the stopped endpoint in its -// cache during this grace period to cover the time gap for the capacity change to -// take effect. -const endpointStopGracePeriod = time.Duration(5) * time.Minute - -// kubeletDeviceManagerCheckpoint is the file name of device plugin checkpoint -const kubeletDeviceManagerCheckpoint = "kubelet_internal_checkpoint" diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/doc.go deleted file mode 100644 index 4f007f7ce..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/doc.go +++ /dev/null @@ -1,21 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package cm (abbreviation of "container manager") and its subpackages contain all the kubelet code -// to manage containers. For example, they contain functions to configure containers' cgroups, -// ensure containers run with the desired QoS, and allocate compute resources like cpus, memory, -// devices... -package cm diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS deleted file mode 100644 index 74bf9b65e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/OWNERS +++ /dev/null @@ -1,2 +0,0 @@ -labels: - - wg/device-management diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go deleted file mode 100644 index b8c2215cc..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/claiminfo.go +++ /dev/null @@ -1,222 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dra - -import ( - "errors" - "fmt" - "slices" - "sync" - - resourceapi "k8s.io/api/resource/v1beta1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/kubernetes/pkg/kubelet/cm/dra/state" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" -) - -// ClaimInfo holds information required -// to prepare and unprepare a resource claim. -// +k8s:deepcopy-gen=true -type ClaimInfo struct { - state.ClaimInfoState - prepared bool -} - -// claimInfoCache is a cache of processed resource claims keyed by namespace/claimname. -type claimInfoCache struct { - sync.RWMutex - checkpointer state.Checkpointer - claimInfo map[string]*ClaimInfo -} - -// newClaimInfoFromClaim creates a new claim info from a resource claim. -// It verifies that the kubelet can handle the claim. -func newClaimInfoFromClaim(claim *resourceapi.ResourceClaim) (*ClaimInfo, error) { - claimInfoState := state.ClaimInfoState{ - ClaimUID: claim.UID, - ClaimName: claim.Name, - Namespace: claim.Namespace, - PodUIDs: sets.New[string](), - DriverState: make(map[string]state.DriverState), - } - if claim.Status.Allocation == nil { - return nil, errors.New("not allocated") - } - for _, result := range claim.Status.Allocation.Devices.Results { - claimInfoState.DriverState[result.Driver] = state.DriverState{} - } - info := &ClaimInfo{ - ClaimInfoState: claimInfoState, - prepared: false, - } - return info, nil -} - -// newClaimInfoFromClaim creates a new claim info from a checkpointed claim info state object. -func newClaimInfoFromState(state *state.ClaimInfoState) *ClaimInfo { - info := &ClaimInfo{ - ClaimInfoState: *state.DeepCopy(), - prepared: false, - } - return info -} - -// setCDIDevices adds a set of CDI devices to the claim info. -func (info *ClaimInfo) addDevice(driverName string, deviceState state.Device) { - if info.DriverState == nil { - info.DriverState = make(map[string]state.DriverState) - } - driverState := info.DriverState[driverName] - driverState.Devices = append(driverState.Devices, deviceState) - info.DriverState[driverName] = driverState -} - -// addPodReference adds a pod reference to the claim info. -func (info *ClaimInfo) addPodReference(podUID types.UID) { - info.PodUIDs.Insert(string(podUID)) -} - -// hasPodReference checks if a pod reference exists in the claim info. -func (info *ClaimInfo) hasPodReference(podUID types.UID) bool { - return info.PodUIDs.Has(string(podUID)) -} - -// deletePodReference deletes a pod reference from the claim info. -func (info *ClaimInfo) deletePodReference(podUID types.UID) { - info.PodUIDs.Delete(string(podUID)) -} - -// setPrepared marks the claim info as prepared. -func (info *ClaimInfo) setPrepared() { - info.prepared = true -} - -// isPrepared checks if claim info is prepared or not. -func (info *ClaimInfo) isPrepared() bool { - return info.prepared -} - -// newClaimInfoCache creates a new claim info cache object, pre-populated from a checkpoint (if present). -func newClaimInfoCache(stateDir, checkpointName string) (*claimInfoCache, error) { - checkpointer, err := state.NewCheckpointer(stateDir, checkpointName) - if err != nil { - return nil, fmt.Errorf("could not initialize checkpoint manager, please drain node and remove dra state file, err: %w", err) - } - - checkpoint, err := checkpointer.GetOrCreate() - if err != nil { - return nil, fmt.Errorf("error calling GetOrCreate() on checkpoint state: %w", err) - } - - cache := &claimInfoCache{ - checkpointer: checkpointer, - claimInfo: make(map[string]*ClaimInfo), - } - - entries, err := checkpoint.GetClaimInfoStateList() - if err != nil { - return nil, fmt.Errorf("error calling GetEntries() on checkpoint: %w", err) - - } - for _, entry := range entries { - info := newClaimInfoFromState(&entry) - cache.claimInfo[info.Namespace+"/"+info.ClaimName] = info - } - - return cache, nil -} - -// withLock runs a function while holding the claimInfoCache lock. -func (cache *claimInfoCache) withLock(f func() error) error { - cache.Lock() - defer cache.Unlock() - return f() -} - -// withRLock runs a function while holding the claimInfoCache rlock. -func (cache *claimInfoCache) withRLock(f func() error) error { - cache.RLock() - defer cache.RUnlock() - return f() -} - -// add adds a new claim info object into the claim info cache. -func (cache *claimInfoCache) add(info *ClaimInfo) *ClaimInfo { - cache.claimInfo[info.Namespace+"/"+info.ClaimName] = info - return info -} - -// contains checks to see if a specific claim info object is already in the cache. -func (cache *claimInfoCache) contains(claimName, namespace string) bool { - _, exists := cache.claimInfo[namespace+"/"+claimName] - return exists -} - -// get gets a specific claim info object from the cache. -func (cache *claimInfoCache) get(claimName, namespace string) (*ClaimInfo, bool) { - info, exists := cache.claimInfo[namespace+"/"+claimName] - return info, exists -} - -// delete deletes a specific claim info object from the cache. -func (cache *claimInfoCache) delete(claimName, namespace string) { - delete(cache.claimInfo, namespace+"/"+claimName) -} - -// hasPodReference checks if there is at least one claim -// that is referenced by the pod with the given UID -// This function is used indirectly by the status manager -// to check if pod can enter termination status -func (cache *claimInfoCache) hasPodReference(uid types.UID) bool { - for _, claimInfo := range cache.claimInfo { - if claimInfo.hasPodReference(uid) { - return true - } - } - return false -} - -// syncToCheckpoint syncs the full claim info cache state to a checkpoint. -func (cache *claimInfoCache) syncToCheckpoint() error { - claimInfoStateList := make(state.ClaimInfoStateList, 0, len(cache.claimInfo)) - for _, infoClaim := range cache.claimInfo { - claimInfoStateList = append(claimInfoStateList, infoClaim.ClaimInfoState) - } - checkpoint, err := state.NewCheckpoint(claimInfoStateList) - if err != nil { - return err - } - return cache.checkpointer.Store(checkpoint) -} - -// cdiDevicesAsList returns a list of CDIDevices from the provided claim info. -// When the request name is non-empty, only devices relevant for that request -// are returned. -func (info *ClaimInfo) cdiDevicesAsList(requestName string) []kubecontainer.CDIDevice { - var cdiDevices []kubecontainer.CDIDevice - for _, driverData := range info.DriverState { - for _, device := range driverData.Devices { - if requestName == "" || len(device.RequestNames) == 0 || slices.Contains(device.RequestNames, requestName) { - for _, cdiDeviceID := range device.CDIDeviceIDs { - cdiDevices = append(cdiDevices, kubecontainer.CDIDevice{Name: cdiDeviceID}) - } - } - } - } - return cdiDevices -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go deleted file mode 100644 index 26043a0fd..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/manager.go +++ /dev/null @@ -1,566 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dra - -import ( - "context" - "fmt" - "strconv" - "time" - - v1 "k8s.io/api/core/v1" - resourceapi "k8s.io/api/resource/v1beta1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/wait" - clientset "k8s.io/client-go/kubernetes" - "k8s.io/dynamic-resource-allocation/resourceclaim" - "k8s.io/klog/v2" - drapb "k8s.io/kubelet/pkg/apis/dra/v1beta1" - dra "k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin" - "k8s.io/kubernetes/pkg/kubelet/cm/dra/state" - "k8s.io/kubernetes/pkg/kubelet/config" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/metrics" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" -) - -// draManagerStateFileName is the file name where dra manager stores its state -const draManagerStateFileName = "dra_manager_state" - -// defaultReconcilePeriod is the default reconciliation period to keep all claim info state in sync. -const defaultReconcilePeriod = 60 * time.Second - -// ActivePodsFunc is a function that returns a list of pods to reconcile. -type ActivePodsFunc func() []*v1.Pod - -// GetNodeFunc is a function that returns the node object using the kubelet's node lister. -type GetNodeFunc func() (*v1.Node, error) - -// ManagerImpl is the structure in charge of managing DRA drivers. -type ManagerImpl struct { - // cache contains cached claim info - cache *claimInfoCache - - // reconcilePeriod is the duration between calls to reconcileLoop. - reconcilePeriod time.Duration - - // activePods is a method for listing active pods on the node - // so all claim info state can be updated in the reconciliation loop. - activePods ActivePodsFunc - - // sourcesReady provides the readiness of kubelet configuration sources such as apiserver update readiness. - // We use it to determine when we can treat pods as inactive and react appropriately. - sourcesReady config.SourcesReady - - // KubeClient reference - kubeClient clientset.Interface - - // getNode is a function that returns the node object using the kubelet's node lister. - getNode GetNodeFunc -} - -// NewManagerImpl creates a new manager. -func NewManagerImpl(kubeClient clientset.Interface, stateFileDirectory string, nodeName types.NodeName) (*ManagerImpl, error) { - claimInfoCache, err := newClaimInfoCache(stateFileDirectory, draManagerStateFileName) - if err != nil { - return nil, fmt.Errorf("failed to create claimInfo cache: %w", err) - } - - // TODO: for now the reconcile period is not configurable. - // We should consider making it configurable in the future. - reconcilePeriod := defaultReconcilePeriod - - manager := &ManagerImpl{ - cache: claimInfoCache, - kubeClient: kubeClient, - reconcilePeriod: reconcilePeriod, - activePods: nil, - sourcesReady: nil, - } - - return manager, nil -} - -func (m *ManagerImpl) GetWatcherHandler() cache.PluginHandler { - // The time that DRA drivers have to come back after being unregistered - // before the kubelet removes their ResourceSlices. - // - // This must be long enough to actually allow stopping a pod and - // starting the replacement (otherwise ResourceSlices get deleted - // unnecessarily) and not too long (otherwise the time window were - // pods might still get scheduled to the node after removal of a - // driver is too long). - // - // 30 seconds might be long enough for a simple container restart. - // If a DRA driver wants to be sure that slices don't get wiped, - // it should use rolling updates. - wipingDelay := 30 * time.Second - return cache.PluginHandler(dra.NewRegistrationHandler(m.kubeClient, m.getNode, wipingDelay)) -} - -// Start starts the reconcile loop of the manager. -func (m *ManagerImpl) Start(ctx context.Context, activePods ActivePodsFunc, getNode GetNodeFunc, sourcesReady config.SourcesReady) error { - m.activePods = activePods - m.getNode = getNode - m.sourcesReady = sourcesReady - go wait.UntilWithContext(ctx, func(ctx context.Context) { m.reconcileLoop(ctx) }, m.reconcilePeriod) - return nil -} - -// reconcileLoop ensures that any stale state in the manager's claimInfoCache gets periodically reconciled. -func (m *ManagerImpl) reconcileLoop(ctx context.Context) { - logger := klog.FromContext(ctx) - // Only once all sources are ready do we attempt to reconcile. - // This ensures that the call to m.activePods() below will succeed with - // the actual active pods list. - if m.sourcesReady == nil || !m.sourcesReady.AllReady() { - return - } - - // Get the full list of active pods. - activePods := sets.New[string]() - for _, p := range m.activePods() { - activePods.Insert(string(p.UID)) - } - - // Get the list of inactive pods still referenced by any claimInfos. - type podClaims struct { - uid types.UID - namespace string - claimNames []string - } - inactivePodClaims := make(map[string]*podClaims) - m.cache.RLock() - for _, claimInfo := range m.cache.claimInfo { - for podUID := range claimInfo.PodUIDs { - if activePods.Has(podUID) { - continue - } - if inactivePodClaims[podUID] == nil { - inactivePodClaims[podUID] = &podClaims{ - uid: types.UID(podUID), - namespace: claimInfo.Namespace, - claimNames: []string{}, - } - } - inactivePodClaims[podUID].claimNames = append(inactivePodClaims[podUID].claimNames, claimInfo.ClaimName) - } - } - m.cache.RUnlock() - - // Loop through all inactive pods and call UnprepareResources on them. - for _, podClaims := range inactivePodClaims { - if err := m.unprepareResources(ctx, podClaims.uid, podClaims.namespace, podClaims.claimNames); err != nil { - logger.Info("Unpreparing pod resources in reconcile loop failed, will retry", "podUID", podClaims.uid, "err", err) - } - } -} - -// PrepareResources attempts to prepare all of the required resources -// for the input container, issue NodePrepareResources rpc requests -// for each new resource requirement, process their responses and update the cached -// containerResources on success. -func (m *ManagerImpl) PrepareResources(ctx context.Context, pod *v1.Pod) error { - startTime := time.Now() - err := m.prepareResources(ctx, pod) - metrics.DRAOperationsDuration.WithLabelValues("PrepareResources", strconv.FormatBool(err == nil)).Observe(time.Since(startTime).Seconds()) - return err -} - -func (m *ManagerImpl) prepareResources(ctx context.Context, pod *v1.Pod) error { - logger := klog.FromContext(ctx) - batches := make(map[string][]*drapb.Claim) - resourceClaims := make(map[types.UID]*resourceapi.ResourceClaim) - for i := range pod.Spec.ResourceClaims { - podClaim := &pod.Spec.ResourceClaims[i] - logger.V(3).Info("Processing resource", "pod", klog.KObj(pod), "podClaim", podClaim.Name) - claimName, mustCheckOwner, err := resourceclaim.Name(pod, podClaim) - if err != nil { - return fmt.Errorf("prepare resource claim: %w", err) - } - - if claimName == nil { - // Nothing to do. - logger.V(5).Info("No need to prepare resources, no claim generated", "pod", klog.KObj(pod), "podClaim", podClaim.Name) - continue - } - // Query claim object from the API server - resourceClaim, err := m.kubeClient.ResourceV1beta1().ResourceClaims(pod.Namespace).Get( - ctx, - *claimName, - metav1.GetOptions{}) - if err != nil { - return fmt.Errorf("failed to fetch ResourceClaim %s referenced by pod %s: %w", *claimName, pod.Name, err) - } - - if mustCheckOwner { - if err = resourceclaim.IsForPod(pod, resourceClaim); err != nil { - return err - } - } - - // Check if pod is in the ReservedFor for the claim - if !resourceclaim.IsReservedForPod(pod, resourceClaim) { - return fmt.Errorf("pod %s(%s) is not allowed to use resource claim %s(%s)", - pod.Name, pod.UID, *claimName, resourceClaim.UID) - } - - // Atomically perform some operations on the claimInfo cache. - err = m.cache.withLock(func() error { - // Get a reference to the claim info for this claim from the cache. - // If there isn't one yet, then add it to the cache. - claimInfo, exists := m.cache.get(resourceClaim.Name, resourceClaim.Namespace) - if !exists { - ci, err := newClaimInfoFromClaim(resourceClaim) - if err != nil { - return fmt.Errorf("claim %s: %w", klog.KObj(resourceClaim), err) - } - claimInfo = m.cache.add(ci) - logger.V(6).Info("Created new claim info cache entry", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo) - } else { - logger.V(6).Info("Found existing claim info cache entry", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim), "claimInfoEntry", claimInfo) - } - - // Add a reference to the current pod in the claim info. - claimInfo.addPodReference(pod.UID) - - // Checkpoint to ensure all claims we plan to prepare are tracked. - // If something goes wrong and the newly referenced pod gets - // deleted without a successful prepare call, we will catch - // that in the reconcile loop and take the appropriate action. - if err := m.cache.syncToCheckpoint(); err != nil { - return fmt.Errorf("failed to checkpoint claimInfo state: %w", err) - } - - // If this claim is already prepared, there is no need to prepare it again. - if claimInfo.isPrepared() { - logger.V(5).Info("Resources already prepared", "pod", klog.KObj(pod), "podClaim", podClaim.Name, "claim", klog.KObj(resourceClaim)) - return nil - } - - // This saved claim will be used to update ClaimInfo cache - // after NodePrepareResources GRPC succeeds - resourceClaims[claimInfo.ClaimUID] = resourceClaim - - // Loop through all drivers and prepare for calling NodePrepareResources. - claim := &drapb.Claim{ - Namespace: claimInfo.Namespace, - UID: string(claimInfo.ClaimUID), - Name: claimInfo.ClaimName, - } - for driverName := range claimInfo.DriverState { - batches[driverName] = append(batches[driverName], claim) - } - - return nil - }) - if err != nil { - return fmt.Errorf("locked cache operation: %w", err) - } - } - - // Call NodePrepareResources for all claims in each batch. - // If there is any error, processing gets aborted. - // We could try to continue, but that would make the code more complex. - for driverName, claims := range batches { - // Call NodePrepareResources RPC for all resource handles. - client, err := dra.NewDRAPluginClient(driverName) - if err != nil { - return fmt.Errorf("failed to get gRPC client for driver %s: %w", driverName, err) - } - response, err := client.NodePrepareResources(ctx, &drapb.NodePrepareResourcesRequest{Claims: claims}) - if err != nil { - // General error unrelated to any particular claim. - return fmt.Errorf("NodePrepareResources failed: %w", err) - } - for claimUID, result := range response.Claims { - reqClaim := lookupClaimRequest(claims, claimUID) - if reqClaim == nil { - return fmt.Errorf("NodePrepareResources returned result for unknown claim UID %s", claimUID) - } - if result.GetError() != "" { - return fmt.Errorf("NodePrepareResources failed for claim %s/%s: %s", reqClaim.Namespace, reqClaim.Name, result.Error) - } - - claim := resourceClaims[types.UID(claimUID)] - - // Add the prepared CDI devices to the claim info - err := m.cache.withLock(func() error { - info, exists := m.cache.get(claim.Name, claim.Namespace) - if !exists { - return fmt.Errorf("unable to get claim info for claim %s in namespace %s", claim.Name, claim.Namespace) - } - for _, device := range result.GetDevices() { - info.addDevice(driverName, state.Device{PoolName: device.PoolName, DeviceName: device.DeviceName, RequestNames: device.RequestNames, CDIDeviceIDs: device.CDIDeviceIDs}) - } - return nil - }) - if err != nil { - return fmt.Errorf("locked cache operation: %w", err) - } - } - - unfinished := len(claims) - len(response.Claims) - if unfinished != 0 { - return fmt.Errorf("NodePrepareResources left out %d claims", unfinished) - } - } - - // Atomically perform some operations on the claimInfo cache. - err := m.cache.withLock(func() error { - // Mark all pod claims as prepared. - for _, claim := range resourceClaims { - info, exists := m.cache.get(claim.Name, claim.Namespace) - if !exists { - return fmt.Errorf("unable to get claim info for claim %s in namespace %s", claim.Name, claim.Namespace) - } - info.setPrepared() - } - - // Checkpoint to ensure all prepared claims are tracked with their list - // of CDI devices attached. - if err := m.cache.syncToCheckpoint(); err != nil { - return fmt.Errorf("failed to checkpoint claimInfo state: %w", err) - } - - return nil - }) - if err != nil { - return fmt.Errorf("locked cache operation: %w", err) - } - - return nil -} - -func lookupClaimRequest(claims []*drapb.Claim, claimUID string) *drapb.Claim { - for _, claim := range claims { - if claim.UID == claimUID { - return claim - } - } - return nil -} - -// GetResources gets a ContainerInfo object from the claimInfo cache. -// This information is used by the caller to update a container config. -func (m *ManagerImpl) GetResources(pod *v1.Pod, container *v1.Container) (*ContainerInfo, error) { - cdiDevices := []kubecontainer.CDIDevice{} - - for i := range pod.Spec.ResourceClaims { - podClaim := &pod.Spec.ResourceClaims[i] - claimName, _, err := resourceclaim.Name(pod, podClaim) - if err != nil { - return nil, fmt.Errorf("list resource claims: %w", err) - } - // The claim name might be nil if no underlying resource claim - // was generated for the referenced claim. There are valid use - // cases when this might happen, so we simply skip it. - if claimName == nil { - continue - } - for _, claim := range container.Resources.Claims { - if podClaim.Name != claim.Name { - continue - } - - err := m.cache.withRLock(func() error { - claimInfo, exists := m.cache.get(*claimName, pod.Namespace) - if !exists { - return fmt.Errorf("unable to get claim info for claim %s in namespace %s", *claimName, pod.Namespace) - } - - // As of Kubernetes 1.31, CDI device IDs are not passed via annotations anymore. - cdiDevices = append(cdiDevices, claimInfo.cdiDevicesAsList(claim.Request)...) - - return nil - }) - if err != nil { - return nil, fmt.Errorf("locked cache operation: %w", err) - } - } - } - return &ContainerInfo{CDIDevices: cdiDevices}, nil -} - -// UnprepareResources calls a driver's NodeUnprepareResource API for each resource claim owned by a pod. -// This function is idempotent and may be called multiple times against the same pod. -// As such, calls to the underlying NodeUnprepareResource API are skipped for claims that have -// already been successfully unprepared. -func (m *ManagerImpl) UnprepareResources(ctx context.Context, pod *v1.Pod) error { - var err error = nil - defer func(startTime time.Time) { - metrics.DRAOperationsDuration.WithLabelValues("UnprepareResources", strconv.FormatBool(err != nil)).Observe(time.Since(startTime).Seconds()) - }(time.Now()) - var claimNames []string - for i := range pod.Spec.ResourceClaims { - claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) - if err != nil { - return fmt.Errorf("unprepare resource claim: %w", err) - } - // The claim name might be nil if no underlying resource claim - // was generated for the referenced claim. There are valid use - // cases when this might happen, so we simply skip it. - if claimName == nil { - continue - } - claimNames = append(claimNames, *claimName) - } - err = m.unprepareResources(ctx, pod.UID, pod.Namespace, claimNames) - return err -} - -func (m *ManagerImpl) unprepareResources(ctx context.Context, podUID types.UID, namespace string, claimNames []string) error { - logger := klog.FromContext(ctx) - batches := make(map[string][]*drapb.Claim) - claimNamesMap := make(map[types.UID]string) - for _, claimName := range claimNames { - // Atomically perform some operations on the claimInfo cache. - err := m.cache.withLock(func() error { - // Get the claim info from the cache - claimInfo, exists := m.cache.get(claimName, namespace) - - // Skip calling NodeUnprepareResource if claim info is not cached - if !exists { - return nil - } - - // Skip calling NodeUnprepareResource if other pods are still referencing it - if len(claimInfo.PodUIDs) > 1 { - // We delay checkpointing of this change until - // UnprepareResources returns successfully. It is OK to do - // this because we will only return successfully from this call - // if the checkpoint has succeeded. That means if the kubelet - // is ever restarted before this checkpoint succeeds, we will - // simply call into this (idempotent) function again. - claimInfo.deletePodReference(podUID) - return nil - } - - // This claimInfo name will be used to update ClaimInfo cache - // after NodeUnprepareResources GRPC succeeds - claimNamesMap[claimInfo.ClaimUID] = claimInfo.ClaimName - - // Loop through all drivers and prepare for calling NodeUnprepareResources. - claim := &drapb.Claim{ - Namespace: claimInfo.Namespace, - UID: string(claimInfo.ClaimUID), - Name: claimInfo.ClaimName, - } - for driverName := range claimInfo.DriverState { - batches[driverName] = append(batches[driverName], claim) - } - - return nil - }) - if err != nil { - return fmt.Errorf("locked cache operation: %w", err) - } - } - - // Call NodeUnprepareResources for all claims in each batch. - // If there is any error, processing gets aborted. - // We could try to continue, but that would make the code more complex. - for driverName, claims := range batches { - // Call NodeUnprepareResources RPC for all resource handles. - client, err := dra.NewDRAPluginClient(driverName) - if err != nil { - return fmt.Errorf("get gRPC client for DRA driver %s: %w", driverName, err) - } - response, err := client.NodeUnprepareResources(ctx, &drapb.NodeUnprepareResourcesRequest{Claims: claims}) - if err != nil { - // General error unrelated to any particular claim. - return fmt.Errorf("NodeUnprepareResources failed: %w", err) - } - - for claimUID, result := range response.Claims { - reqClaim := lookupClaimRequest(claims, claimUID) - if reqClaim == nil { - return fmt.Errorf("NodeUnprepareResources returned result for unknown claim UID %s", claimUID) - } - if result.GetError() != "" { - return fmt.Errorf("NodeUnprepareResources failed for claim %s/%s: %s", reqClaim.Namespace, reqClaim.Name, result.Error) - } - } - - unfinished := len(claims) - len(response.Claims) - if unfinished != 0 { - return fmt.Errorf("NodeUnprepareResources left out %d claims", unfinished) - } - } - - // Atomically perform some operations on the claimInfo cache. - err := m.cache.withLock(func() error { - // Delete all claimInfos from the cache that have just been unprepared. - for _, claimName := range claimNamesMap { - claimInfo, _ := m.cache.get(claimName, namespace) - m.cache.delete(claimName, namespace) - logger.V(6).Info("Deleted claim info cache entry", "claim", klog.KRef(namespace, claimName), "claimInfoEntry", claimInfo) - } - - // Atomically sync the cache back to the checkpoint. - if err := m.cache.syncToCheckpoint(); err != nil { - return fmt.Errorf("failed to checkpoint claimInfo state: %w", err) - } - return nil - }) - if err != nil { - return fmt.Errorf("locked cache operation: %w", err) - } - - return nil -} - -// PodMightNeedToUnprepareResources returns true if the pod might need to -// unprepare resources -func (m *ManagerImpl) PodMightNeedToUnprepareResources(uid types.UID) bool { - m.cache.Lock() - defer m.cache.Unlock() - return m.cache.hasPodReference(uid) -} - -// GetContainerClaimInfos gets Container's ClaimInfo -func (m *ManagerImpl) GetContainerClaimInfos(pod *v1.Pod, container *v1.Container) ([]*ClaimInfo, error) { - claimInfos := make([]*ClaimInfo, 0, len(pod.Spec.ResourceClaims)) - - for i, podResourceClaim := range pod.Spec.ResourceClaims { - claimName, _, err := resourceclaim.Name(pod, &pod.Spec.ResourceClaims[i]) - if err != nil { - return nil, fmt.Errorf("determine resource claim information: %w", err) - } - - for _, claim := range container.Resources.Claims { - if podResourceClaim.Name != claim.Name { - continue - } - - err := m.cache.withRLock(func() error { - claimInfo, exists := m.cache.get(*claimName, pod.Namespace) - if !exists { - return fmt.Errorf("unable to get claim info for claim %s in namespace %s", *claimName, pod.Namespace) - } - claimInfos = append(claimInfos, claimInfo.DeepCopy()) - return nil - }) - if err != nil { - return nil, fmt.Errorf("locked cache operation: %w", err) - } - } - } - return claimInfos, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugin.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugin.go deleted file mode 100644 index 4f7b7a99e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugin.go +++ /dev/null @@ -1,181 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package plugin - -import ( - "context" - "errors" - "fmt" - "net" - "sync" - "time" - - "google.golang.org/grpc" - "google.golang.org/grpc/connectivity" - "google.golang.org/grpc/credentials/insecure" - "google.golang.org/grpc/status" - - "k8s.io/klog/v2" - drapbv1alpha4 "k8s.io/kubelet/pkg/apis/dra/v1alpha4" - drapbv1beta1 "k8s.io/kubelet/pkg/apis/dra/v1beta1" - "k8s.io/kubernetes/pkg/kubelet/metrics" -) - -// NewDRAPluginClient returns a wrapper around those gRPC methods of a DRA -// driver kubelet plugin which need to be called by kubelet. The wrapper -// handles gRPC connection management and logging. Connections are reused -// across different NewDRAPluginClient calls. -func NewDRAPluginClient(pluginName string) (*Plugin, error) { - if pluginName == "" { - return nil, fmt.Errorf("plugin name is empty") - } - - existingPlugin := draPlugins.get(pluginName) - if existingPlugin == nil { - return nil, fmt.Errorf("plugin name %s not found in the list of registered DRA plugins", pluginName) - } - - return existingPlugin, nil -} - -type Plugin struct { - name string - backgroundCtx context.Context - cancel func(cause error) - - mutex sync.Mutex - conn *grpc.ClientConn - endpoint string - chosenService string // e.g. drapbv1beta1.DRAPluginService - clientCallTimeout time.Duration -} - -func (p *Plugin) getOrCreateGRPCConn() (*grpc.ClientConn, error) { - p.mutex.Lock() - defer p.mutex.Unlock() - - if p.conn != nil { - return p.conn, nil - } - - ctx := p.backgroundCtx - logger := klog.FromContext(ctx) - - network := "unix" - logger.V(4).Info("Creating new gRPC connection", "protocol", network, "endpoint", p.endpoint) - // grpc.Dial is deprecated. grpc.NewClient should be used instead. - // For now this gets ignored because this function is meant to establish - // the connection, with the one second timeout below. Perhaps that - // approach should be reconsidered? - //nolint:staticcheck - conn, err := grpc.Dial( - p.endpoint, - grpc.WithTransportCredentials(insecure.NewCredentials()), - grpc.WithContextDialer(func(ctx context.Context, target string) (net.Conn, error) { - return (&net.Dialer{}).DialContext(ctx, network, target) - }), - grpc.WithChainUnaryInterceptor(newMetricsInterceptor(p.name)), - ) - if err != nil { - return nil, err - } - - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - defer cancel() - - if ok := conn.WaitForStateChange(ctx, connectivity.Connecting); !ok { - return nil, errors.New("timed out waiting for gRPC connection to be ready") - } - - p.conn = conn - return p.conn, nil -} - -func (p *Plugin) NodePrepareResources( - ctx context.Context, - req *drapbv1beta1.NodePrepareResourcesRequest, - opts ...grpc.CallOption, -) (*drapbv1beta1.NodePrepareResourcesResponse, error) { - logger := klog.FromContext(ctx) - logger.V(4).Info("Calling NodePrepareResources rpc", "request", req) - - conn, err := p.getOrCreateGRPCConn() - if err != nil { - return nil, err - } - - ctx, cancel := context.WithTimeout(ctx, p.clientCallTimeout) - defer cancel() - - var response *drapbv1beta1.NodePrepareResourcesResponse - switch p.chosenService { - case drapbv1beta1.DRAPluginService: - nodeClient := drapbv1beta1.NewDRAPluginClient(conn) - response, err = nodeClient.NodePrepareResources(ctx, req) - case drapbv1alpha4.NodeService: - nodeClient := drapbv1alpha4.NewNodeClient(conn) - response, err = drapbv1alpha4.V1Alpha4ClientWrapper{NodeClient: nodeClient}.NodePrepareResources(ctx, req) - default: - // Shouldn't happen, validateSupportedServices should only - // return services we support here. - return nil, fmt.Errorf("internal error: unsupported chosen service: %q", p.chosenService) - } - logger.V(4).Info("Done calling NodePrepareResources rpc", "response", response, "err", err) - return response, err -} - -func (p *Plugin) NodeUnprepareResources( - ctx context.Context, - req *drapbv1beta1.NodeUnprepareResourcesRequest, - opts ...grpc.CallOption, -) (*drapbv1beta1.NodeUnprepareResourcesResponse, error) { - logger := klog.FromContext(ctx) - logger.V(4).Info("Calling NodeUnprepareResource rpc", "request", req) - - conn, err := p.getOrCreateGRPCConn() - if err != nil { - return nil, err - } - - ctx, cancel := context.WithTimeout(ctx, p.clientCallTimeout) - defer cancel() - - var response *drapbv1beta1.NodeUnprepareResourcesResponse - switch p.chosenService { - case drapbv1beta1.DRAPluginService: - nodeClient := drapbv1beta1.NewDRAPluginClient(conn) - response, err = nodeClient.NodeUnprepareResources(ctx, req) - case drapbv1alpha4.NodeService: - nodeClient := drapbv1alpha4.NewNodeClient(conn) - response, err = drapbv1alpha4.V1Alpha4ClientWrapper{NodeClient: nodeClient}.NodeUnprepareResources(ctx, req) - default: - // Shouldn't happen, validateSupportedServices should only - // return services we support here. - return nil, fmt.Errorf("internal error: unsupported chosen service: %q", p.chosenService) - } - logger.V(4).Info("Done calling NodeUnprepareResources rpc", "response", response, "err", err) - return response, err -} - -func newMetricsInterceptor(pluginName string) grpc.UnaryClientInterceptor { - return func(ctx context.Context, method string, req, reply any, conn *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - start := time.Now() - err := invoker(ctx, method, req, reply, conn, opts...) - metrics.DRAGRPCOperationsDuration.WithLabelValues(pluginName, method, status.Code(err).String()).Observe(time.Since(start).Seconds()) - return err - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugins_store.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugins_store.go deleted file mode 100644 index cc2fc240b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/plugins_store.go +++ /dev/null @@ -1,96 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package plugin - -import ( - "errors" - "fmt" - "slices" - "sync" -) - -// PluginsStore holds a list of DRA Plugins. -type pluginsStore struct { - sync.RWMutex - // plugin name -> Plugin in the order in which they got added - store map[string][]*Plugin -} - -// draPlugins map keeps track of all registered DRA plugins on the node -// and their corresponding sockets. -var draPlugins = &pluginsStore{} - -// Get lets you retrieve a DRA Plugin by name. -// This method is protected by a mutex. -func (s *pluginsStore) get(pluginName string) *Plugin { - s.RLock() - defer s.RUnlock() - - instances := s.store[pluginName] - if len(instances) == 0 { - return nil - } - // Heuristic: pick the most recent one. It's most likely - // the newest, except when kubelet got restarted and registered - // all running plugins in random order. - return instances[len(instances)-1] -} - -// Set lets you save a DRA Plugin to the list and give it a specific name. -// This method is protected by a mutex. -func (s *pluginsStore) add(p *Plugin) error { - s.Lock() - defer s.Unlock() - - if s.store == nil { - s.store = make(map[string][]*Plugin) - } - for _, oldP := range s.store[p.name] { - if oldP.endpoint == p.endpoint { - // One plugin instance cannot hijack the endpoint of another instance. - return fmt.Errorf("endpoint %s already registered for plugin %s", p.endpoint, p.name) - } - } - s.store[p.name] = append(s.store[p.name], p) - return nil -} - -// remove lets you remove one endpoint for a DRA Plugin. -// This method is protected by a mutex. It returns the -// plugin if found and true if that was the last instance -func (s *pluginsStore) remove(pluginName, endpoint string) (*Plugin, bool) { - s.Lock() - defer s.Unlock() - - instances := s.store[pluginName] - i := slices.IndexFunc(instances, func(p *Plugin) bool { return p.endpoint == endpoint }) - if i == -1 { - return nil, false - } - p := instances[i] - last := len(instances) == 1 - if last { - delete(s.store, pluginName) - } else { - s.store[pluginName] = slices.Delete(instances, i, i+1) - } - - if p.cancel != nil { - p.cancel(errors.New("plugin got removed")) - } - return p, last -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/registration.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/registration.go deleted file mode 100644 index 0f410c429..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin/registration.go +++ /dev/null @@ -1,345 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package plugin - -import ( - "context" - "errors" - "fmt" - "slices" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - resourceapi "k8s.io/api/resource/v1beta1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/kubernetes" - "k8s.io/klog/v2" - drapbv1alpha4 "k8s.io/kubelet/pkg/apis/dra/v1alpha4" - drapbv1beta1 "k8s.io/kubelet/pkg/apis/dra/v1beta1" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" -) - -// defaultClientCallTimeout is the default amount of time that a DRA driver has -// to respond to any of the gRPC calls. kubelet uses this value by passing nil -// to RegisterPlugin. Some tests use a different, usually shorter timeout to -// speed up testing. -// -// This is half of the kubelet retry period (according to -// https://github.com/kubernetes/kubernetes/commit/0449cef8fd5217d394c5cd331d852bd50983e6b3). -const defaultClientCallTimeout = 45 * time.Second - -// RegistrationHandler is the handler which is fed to the pluginwatcher API. -type RegistrationHandler struct { - // backgroundCtx is used for all future activities of the handler. - // This is necessary because it implements APIs which don't - // provide a context. - backgroundCtx context.Context - cancel func(err error) - kubeClient kubernetes.Interface - getNode func() (*v1.Node, error) - wipingDelay time.Duration - - wg sync.WaitGroup - mutex sync.Mutex - - // pendingWipes maps a plugin name to a cancel function for - // wiping of that plugin's ResourceSlices. Entries get added - // in DeRegisterPlugin and check in RegisterPlugin. If - // wiping is pending during RegisterPlugin, it gets canceled. - // - // Must use pointers to functions because the entries have to - // be comparable. - pendingWipes map[string]*context.CancelCauseFunc -} - -var _ cache.PluginHandler = &RegistrationHandler{} - -// NewPluginHandler returns new registration handler. -// -// Must only be called once per process because it manages global state. -// If a kubeClient is provided, then it synchronizes ResourceSlices -// with the resource information provided by plugins. -func NewRegistrationHandler(kubeClient kubernetes.Interface, getNode func() (*v1.Node, error), wipingDelay time.Duration) *RegistrationHandler { - // The context and thus logger should come from the caller. - return newRegistrationHandler(context.TODO(), kubeClient, getNode, wipingDelay) -} - -func newRegistrationHandler(ctx context.Context, kubeClient kubernetes.Interface, getNode func() (*v1.Node, error), wipingDelay time.Duration) *RegistrationHandler { - ctx, cancel := context.WithCancelCause(ctx) - handler := &RegistrationHandler{ - backgroundCtx: klog.NewContext(ctx, klog.LoggerWithName(klog.FromContext(ctx), "DRA registration handler")), - cancel: cancel, - kubeClient: kubeClient, - getNode: getNode, - wipingDelay: wipingDelay, - pendingWipes: make(map[string]*context.CancelCauseFunc), - } - - // When kubelet starts up, no DRA driver has registered yet. None of - // the drivers are usable until they come back, which might not happen - // at all. Therefore it is better to not advertise any local resources - // because pods could get stuck on the node waiting for the driver - // to start up. - // - // This has to run in the background. - handler.wg.Add(1) - go func() { - defer handler.wg.Done() - - logger := klog.LoggerWithName(klog.FromContext(handler.backgroundCtx), "startup") - ctx := klog.NewContext(handler.backgroundCtx, logger) - handler.wipeResourceSlices(ctx, 0 /* no delay */, "" /* all drivers */) - }() - - return handler -} - -// Stop cancels any remaining background activities and blocks until all goroutines have stopped. -func (h *RegistrationHandler) Stop() { - h.cancel(errors.New("Stop was called")) - h.wg.Wait() -} - -// wipeResourceSlices deletes ResourceSlices of the node, optionally just for a specific driver. -// Wiping will delay for a while and can be canceled by canceling the context. -func (h *RegistrationHandler) wipeResourceSlices(ctx context.Context, delay time.Duration, driver string) { - if h.kubeClient == nil { - return - } - logger := klog.FromContext(ctx) - - if delay != 0 { - // Before we start deleting, give the driver time to bounce back. - // Perhaps it got removed as part of a DaemonSet update and the - // replacement pod is about to start. - logger.V(4).Info("Starting to wait before wiping ResourceSlices", "delay", delay) - select { - case <-ctx.Done(): - logger.V(4).Info("Aborting wiping of ResourceSlices", "reason", context.Cause(ctx)) - case <-time.After(delay): - logger.V(4).Info("Starting to wipe ResourceSlices after waiting", "delay", delay) - } - } - - backoff := wait.Backoff{ - Duration: time.Second, - Factor: 2, - Jitter: 0.2, - Cap: 5 * time.Minute, - Steps: 100, - } - - // Error logging is done inside the loop. Context cancellation doesn't get logged. - _ = wait.ExponentialBackoffWithContext(ctx, backoff, func(ctx context.Context) (bool, error) { - node, err := h.getNode() - if apierrors.IsNotFound(err) { - return false, nil - } - if err != nil { - logger.Error(err, "Unexpected error checking for node") - return false, nil - } - fieldSelector := fields.Set{resourceapi.ResourceSliceSelectorNodeName: node.Name} - if driver != "" { - fieldSelector[resourceapi.ResourceSliceSelectorDriver] = driver - } - - err = h.kubeClient.ResourceV1beta1().ResourceSlices().DeleteCollection(ctx, metav1.DeleteOptions{}, metav1.ListOptions{FieldSelector: fieldSelector.String()}) - switch { - case err == nil: - logger.V(3).Info("Deleted ResourceSlices", "fieldSelector", fieldSelector) - return true, nil - case apierrors.IsUnauthorized(err): - // This can happen while kubelet is still figuring out - // its credentials. - logger.V(5).Info("Deleting ResourceSlice failed, retrying", "fieldSelector", fieldSelector, "err", err) - return false, nil - default: - // Log and retry for other errors. - logger.V(3).Info("Deleting ResourceSlice failed, retrying", "fieldSelector", fieldSelector, "err", err) - return false, nil - } - }) -} - -// RegisterPlugin is called when a plugin can be registered. -// -// DRA uses the version array in the registration API to enumerate all gRPC -// services that the plugin provides, using the "." format (e.g. "v1beta1.DRAPlugin"). This allows kubelet to determine -// in advance which version to use resp. which optional services the plugin -// supports. -func (h *RegistrationHandler) RegisterPlugin(pluginName string, endpoint string, supportedServices []string, pluginClientTimeout *time.Duration) error { - // Prepare a context with its own logger for the plugin. - // - // The lifecycle of the plugin's background activities is tied to our - // root context, so canceling that will also cancel the plugin. - // - // The logger injects the plugin name as additional value - // into all log output related to the plugin. - ctx := h.backgroundCtx - logger := klog.FromContext(ctx) - logger = klog.LoggerWithValues(logger, "pluginName", pluginName, "endpoint", endpoint) - ctx = klog.NewContext(ctx, logger) - - logger.V(3).Info("Register new DRA plugin") - - chosenService, err := h.validateSupportedServices(pluginName, supportedServices) - if err != nil { - return fmt.Errorf("version check of plugin %s failed: %w", pluginName, err) - } - - var timeout time.Duration - if pluginClientTimeout == nil { - timeout = defaultClientCallTimeout - } else { - timeout = *pluginClientTimeout - } - - ctx, cancel := context.WithCancelCause(ctx) - - pluginInstance := &Plugin{ - name: pluginName, - backgroundCtx: ctx, - cancel: cancel, - conn: nil, - endpoint: endpoint, - chosenService: chosenService, - clientCallTimeout: timeout, - } - - // Storing endpoint of newly registered DRA Plugin into the map, where plugin name will be the key - // all other DRA components will be able to get the actual socket of DRA plugins by its name. - if err := draPlugins.add(pluginInstance); err != nil { - cancel(err) - // No wrapping, the error already contains details. - return err - } - - // Now cancel any pending ResourceSlice wiping for this plugin. - // Only needs to be done once. - h.mutex.Lock() - defer h.mutex.Unlock() - if cancel := h.pendingWipes[pluginName]; cancel != nil { - (*cancel)(errors.New("new plugin instance registered")) - delete(h.pendingWipes, pluginName) - } - - return nil -} - -// validateSupportedServices identifies the highest supported gRPC service for -// NodePrepareResources and NodeUnprepareResources and returns its name -// (e.g. [drapbv1beta1.DRAPluginService]). An error is returned if the plugin -// is unusable. -func (h *RegistrationHandler) validateSupportedServices(pluginName string, supportedServices []string) (string, error) { - if len(supportedServices) == 0 { - return "", errors.New("empty list of supported gRPC services (aka supported versions)") - } - - // Pick most recent version if available. - chosenService := "" - for _, service := range []string{ - // Sorted by most recent first, oldest last. - drapbv1beta1.DRAPluginService, - drapbv1alpha4.NodeService, - } { - if slices.Contains(supportedServices, service) { - chosenService = service - break - } - } - - // Fall back to alpha if necessary because - // plugins at that time didn't advertise gRPC services. - if chosenService == "" { - chosenService = drapbv1alpha4.NodeService - } - - return chosenService, nil -} - -// DeRegisterPlugin is called when a plugin has removed its socket, -// signaling it is no longer available. -func (h *RegistrationHandler) DeRegisterPlugin(pluginName, endpoint string) { - if p, last := draPlugins.remove(pluginName, endpoint); p != nil { - // This logger includes endpoint and pluginName. - logger := klog.FromContext(p.backgroundCtx) - logger.V(3).Info("Deregister DRA plugin", "lastInstance", last) - if !last { - return - } - - // Prepare for canceling the background wiping. This needs to run - // in the context of the registration handler, the one from - // the plugin is canceled. - logger = klog.FromContext(h.backgroundCtx) - logger = klog.LoggerWithName(logger, "driver-cleanup") - logger = klog.LoggerWithValues(logger, "pluginName", pluginName) - ctx, cancel := context.WithCancelCause(h.backgroundCtx) - ctx = klog.NewContext(ctx, logger) - - // Clean up the ResourceSlices for the deleted Plugin since it - // may have died without doing so itself and might never come - // back. - // - // May get canceled if the plugin comes back quickly enough - // (see RegisterPlugin). - h.mutex.Lock() - defer h.mutex.Unlock() - if cancel := h.pendingWipes[pluginName]; cancel != nil { - (*cancel)(errors.New("plugin deregistered a second time")) - } - h.pendingWipes[pluginName] = &cancel - - h.wg.Add(1) - go func() { - defer h.wg.Done() - defer func() { - h.mutex.Lock() - defer h.mutex.Unlock() - - // Cancel our own context, but remove it from the map only if it - // is the current entry. Perhaps it already got replaced. - cancel(errors.New("wiping done")) - if h.pendingWipes[pluginName] == &cancel { - delete(h.pendingWipes, pluginName) - } - }() - h.wipeResourceSlices(ctx, h.wipingDelay, pluginName) - }() - return - } - - logger := klog.FromContext(h.backgroundCtx) - logger.V(3).Info("Deregister DRA plugin not necessary, was already removed") -} - -// ValidatePlugin is called by kubelet's plugin watcher upon detection -// of a new registration socket opened by DRA plugin. -func (h *RegistrationHandler) ValidatePlugin(pluginName string, endpoint string, supportedServices []string) error { - _, err := h.validateSupportedServices(pluginName, supportedServices) - if err != nil { - return fmt.Errorf("invalid versions of plugin %s: %w", pluginName, err) - } - - return err -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpoint.go deleted file mode 100644 index bfbae956b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpoint.go +++ /dev/null @@ -1,107 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "encoding/json" - "hash/crc32" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" -) - -const ( - CheckpointAPIGroup = "checkpoint.dra.kubelet.k8s.io" - CheckpointKind = "DRACheckpoint" - CheckpointAPIVersion = CheckpointAPIGroup + "/v1" -) - -// Checkpoint represents a structure to store DRA checkpoint data -type Checkpoint struct { - // Data is a JSON serialized checkpoint data - Data string - // Checksum is a checksum of Data - Checksum uint32 -} - -type CheckpointData struct { - metav1.TypeMeta - ClaimInfoStateList ClaimInfoStateList -} - -// NewCheckpoint creates a new checkpoint from a list of claim info states -func NewCheckpoint(data ClaimInfoStateList) (*Checkpoint, error) { - cpData := &CheckpointData{ - TypeMeta: metav1.TypeMeta{ - Kind: CheckpointKind, - APIVersion: CheckpointAPIVersion, - }, - ClaimInfoStateList: data, - } - - cpDataBytes, err := json.Marshal(cpData) - if err != nil { - return nil, err - } - - cp := &Checkpoint{ - Data: string(cpDataBytes), - Checksum: crc32.ChecksumIEEE(cpDataBytes), - } - - return cp, nil -} - -// MarshalCheckpoint marshals checkpoint to JSON -func (cp *Checkpoint) MarshalCheckpoint() ([]byte, error) { - return json.Marshal(cp) -} - -// UnmarshalCheckpoint unmarshals checkpoint from JSON -// and verifies its data checksum -func (cp *Checkpoint) UnmarshalCheckpoint(blob []byte) error { - if err := json.Unmarshal(blob, cp); err != nil { - return err - } - - // verify checksum - if err := cp.VerifyChecksum(); err != nil { - return err - } - - return nil -} - -// VerifyChecksum verifies that current checksum -// of checkpointed Data is valid -func (cp *Checkpoint) VerifyChecksum() error { - expectedCS := crc32.ChecksumIEEE([]byte(cp.Data)) - if expectedCS != cp.Checksum { - return &errors.CorruptCheckpointError{ActualCS: uint64(cp.Checksum), ExpectedCS: uint64(expectedCS)} - } - return nil -} - -// GetClaimInfoStateList returns list of claim info states from checkpoint -func (cp *Checkpoint) GetClaimInfoStateList() (ClaimInfoStateList, error) { - var data CheckpointData - if err := json.Unmarshal([]byte(cp.Data), &data); err != nil { - return nil, err - } - - return data.ClaimInfoStateList, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpointer.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpointer.go deleted file mode 100644 index 62f98029f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/checkpointer.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "errors" - "fmt" - "sync" - - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - checkpointerrors "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" -) - -type Checkpointer interface { - GetOrCreate() (*Checkpoint, error) - Store(*Checkpoint) error -} - -type checkpointer struct { - sync.RWMutex - checkpointManager checkpointmanager.CheckpointManager - checkpointName string -} - -// NewCheckpointer creates new checkpointer for keeping track of claim info with checkpoint backend -func NewCheckpointer(stateDir, checkpointName string) (Checkpointer, error) { - if len(checkpointName) == 0 { - return nil, fmt.Errorf("received empty string instead of checkpointName") - } - - checkpointManager, err := checkpointmanager.NewCheckpointManager(stateDir) - if err != nil { - return nil, fmt.Errorf("failed to initialize checkpoint manager: %w", err) - } - - checkpointer := &checkpointer{ - checkpointManager: checkpointManager, - checkpointName: checkpointName, - } - - return checkpointer, nil -} - -// GetOrCreate gets list of claim info states from a checkpoint -// or creates empty list if checkpoint doesn't exist -func (sc *checkpointer) GetOrCreate() (*Checkpoint, error) { - sc.Lock() - defer sc.Unlock() - - checkpoint, err := NewCheckpoint(nil) - if err != nil { - return nil, fmt.Errorf("failed to create new checkpoint: %w", err) - } - - err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpoint) - if errors.Is(err, checkpointerrors.ErrCheckpointNotFound) { - err = sc.store(checkpoint) - if err != nil { - return nil, fmt.Errorf("failed to store checkpoint %v: %w", sc.checkpointName, err) - } - return checkpoint, nil - } - if err != nil { - return nil, fmt.Errorf("failed to get checkpoint %v: %w", sc.checkpointName, err) - } - - return checkpoint, nil -} - -// Store stores checkpoint to the file -func (sc *checkpointer) Store(checkpoint *Checkpoint) error { - sc.Lock() - defer sc.Unlock() - - return sc.store(checkpoint) -} - -// store saves state to a checkpoint, caller is responsible for locking -func (sc *checkpointer) store(checkpoint *Checkpoint) error { - if err := sc.checkpointManager.CreateCheckpoint(sc.checkpointName, checkpoint); err != nil { - return fmt.Errorf("could not save checkpoint %s: %w", sc.checkpointName, err) - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go deleted file mode 100644 index 045a9b6b2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/state.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" -) - -type ClaimInfoStateList []ClaimInfoState - -// +k8s:deepcopy-gen=true -type ClaimInfoState struct { - // ClaimUID is the UID of a resource claim - ClaimUID types.UID - - // ClaimName is the name of a resource claim - ClaimName string - - // Namespace is a claim namespace - Namespace string - - // PodUIDs is a set of pod UIDs that reference a resource - PodUIDs sets.Set[string] - - // DriverState contains information about all drivers which have allocation - // results in the claim, even if they don't provide devices for their results. - DriverState map[string]DriverState -} - -// DriverState is used to store per-device claim info state in a checkpoint -// +k8s:deepcopy-gen=true -type DriverState struct { - Devices []Device -} - -// Device is how a DRA driver described an allocated device in a claim -// to kubelet. RequestName and CDI device IDs are optional. -// +k8s:deepcopy-gen=true -type Device struct { - PoolName string - DeviceName string - RequestNames []string - CDIDeviceIDs []string -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/zz_generated.deepcopy.go deleted file mode 100644 index 6489dab7a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/state/zz_generated.deepcopy.go +++ /dev/null @@ -1,105 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package state - -import ( - sets "k8s.io/apimachinery/pkg/util/sets" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClaimInfoState) DeepCopyInto(out *ClaimInfoState) { - *out = *in - if in.PodUIDs != nil { - in, out := &in.PodUIDs, &out.PodUIDs - *out = make(sets.Set[string], len(*in)) - for key, val := range *in { - (*out)[key] = val - } - } - if in.DriverState != nil { - in, out := &in.DriverState, &out.DriverState - *out = make(map[string]DriverState, len(*in)) - for key, val := range *in { - (*out)[key] = *val.DeepCopy() - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClaimInfoState. -func (in *ClaimInfoState) DeepCopy() *ClaimInfoState { - if in == nil { - return nil - } - out := new(ClaimInfoState) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Device) DeepCopyInto(out *Device) { - *out = *in - if in.RequestNames != nil { - in, out := &in.RequestNames, &out.RequestNames - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.CDIDeviceIDs != nil { - in, out := &in.CDIDeviceIDs, &out.CDIDeviceIDs - *out = make([]string, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Device. -func (in *Device) DeepCopy() *Device { - if in == nil { - return nil - } - out := new(Device) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DriverState) DeepCopyInto(out *DriverState) { - *out = *in - if in.Devices != nil { - in, out := &in.Devices, &out.Devices - *out = make([]Device, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DriverState. -func (in *DriverState) DeepCopy() *DriverState { - if in == nil { - return nil - } - out := new(DriverState) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/types.go deleted file mode 100644 index eafd4914e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/types.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dra - -import ( - "context" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/kubernetes/pkg/kubelet/config" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" -) - -// Manager manages all the DRA resource plugins running on a node. -type Manager interface { - // GetWatcherHandler returns the plugin handler for the DRA. - GetWatcherHandler() cache.PluginHandler - - // Start starts the reconcile loop of the manager. - // This will ensure that all claims are unprepared even if pods get deleted unexpectedly. - Start(ctx context.Context, activePods ActivePodsFunc, getNode GetNodeFunc, sourcesReady config.SourcesReady) error - - // PrepareResources prepares resources for a pod. - // It communicates with the DRA resource plugin to prepare resources. - PrepareResources(ctx context.Context, pod *v1.Pod) error - - // UnprepareResources calls NodeUnprepareResource GRPC from DRA plugin to unprepare pod resources - UnprepareResources(ctx context.Context, pod *v1.Pod) error - - // GetResources gets a ContainerInfo object from the claimInfo cache. - // This information is used by the caller to update a container config. - GetResources(pod *v1.Pod, container *v1.Container) (*ContainerInfo, error) - - // PodMightNeedToUnprepareResources returns true if the pod with the given UID - // might need to unprepare resources. - PodMightNeedToUnprepareResources(UID types.UID) bool - - // GetContainerClaimInfos gets Container ClaimInfo objects - GetContainerClaimInfos(pod *v1.Pod, container *v1.Container) ([]*ClaimInfo, error) -} - -// ContainerInfo contains information required by the runtime to consume prepared resources. -type ContainerInfo struct { - // CDI Devices for the container - CDIDevices []kubecontainer.CDIDevice -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/zz_generated.deepcopy.go deleted file mode 100644 index 577fd4318..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/dra/zz_generated.deepcopy.go +++ /dev/null @@ -1,39 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package dra - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ClaimInfo) DeepCopyInto(out *ClaimInfo) { - *out = *in - in.ClaimInfoState.DeepCopyInto(&out.ClaimInfoState) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClaimInfo. -func (in *ClaimInfo) DeepCopy() *ClaimInfo { - if in == nil { - return nil - } - out := new(ClaimInfo) - in.DeepCopyInto(out) - return out -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go deleted file mode 100644 index dee9ccc22..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_container_manager.go +++ /dev/null @@ -1,278 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "context" - "sync" - - v1 "k8s.io/api/core/v1" - - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apiserver/pkg/server/healthz" - internalapi "k8s.io/cri-api/pkg/apis" - podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" - "k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/config" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" - "k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache" - "k8s.io/kubernetes/pkg/kubelet/status" - schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" -) - -type FakeContainerManager struct { - sync.Mutex - CalledFunctions []string - PodContainerManager *FakePodContainerManager - shouldResetExtendedResourceCapacity bool -} - -var _ ContainerManager = &FakeContainerManager{} - -func NewFakeContainerManager() *FakeContainerManager { - return &FakeContainerManager{ - PodContainerManager: NewFakePodContainerManager(), - } -} - -func (cm *FakeContainerManager) Start(_ context.Context, _ *v1.Node, _ ActivePodsFunc, _ GetNodeFunc, _ config.SourcesReady, _ status.PodStatusProvider, _ internalapi.RuntimeService, _ bool) error { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "Start") - return nil -} - -func (cm *FakeContainerManager) SystemCgroupsLimit() v1.ResourceList { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "SystemCgroupsLimit") - return v1.ResourceList{} -} - -func (cm *FakeContainerManager) GetNodeConfig() NodeConfig { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetNodeConfig") - return NodeConfig{} -} - -func (cm *FakeContainerManager) GetMountedSubsystems() *CgroupSubsystems { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetMountedSubsystems") - return &CgroupSubsystems{} -} - -func (cm *FakeContainerManager) GetQOSContainersInfo() QOSContainersInfo { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "QOSContainersInfo") - return QOSContainersInfo{} -} - -func (cm *FakeContainerManager) UpdateQOSCgroups() error { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "UpdateQOSCgroups") - return nil -} - -func (cm *FakeContainerManager) Status() Status { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "Status") - return Status{} -} - -func (cm *FakeContainerManager) GetNodeAllocatableReservation() v1.ResourceList { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetNodeAllocatableReservation") - return nil -} - -func (cm *FakeContainerManager) GetCapacity(localStorageCapacityIsolation bool) v1.ResourceList { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetCapacity") - if !localStorageCapacityIsolation { - return v1.ResourceList{} - } - c := v1.ResourceList{ - v1.ResourceEphemeralStorage: *resource.NewQuantity( - int64(0), - resource.BinarySI), - } - return c -} - -func (cm *FakeContainerManager) GetPluginRegistrationHandlers() map[string]cache.PluginHandler { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetPluginRegistrationHandlers") - return nil -} - -func (cm *FakeContainerManager) GetHealthCheckers() []healthz.HealthChecker { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetPluginRegistrationServerChecker") - return []healthz.HealthChecker{} -} - -func (cm *FakeContainerManager) GetDevicePluginResourceCapacity() (v1.ResourceList, v1.ResourceList, []string) { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetDevicePluginResourceCapacity") - return nil, nil, []string{} -} - -func (cm *FakeContainerManager) NewPodContainerManager() PodContainerManager { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "PodContainerManager") - return cm.PodContainerManager -} - -func (cm *FakeContainerManager) GetResources(ctx context.Context, pod *v1.Pod, container *v1.Container) (*kubecontainer.RunContainerOptions, error) { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetResources") - return &kubecontainer.RunContainerOptions{}, nil -} - -func (cm *FakeContainerManager) UpdatePluginResources(*schedulerframework.NodeInfo, *lifecycle.PodAdmitAttributes) error { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "UpdatePluginResources") - return nil -} - -func (cm *FakeContainerManager) InternalContainerLifecycle() InternalContainerLifecycle { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "InternalContainerLifecycle") - return &internalContainerLifecycleImpl{cpumanager.NewFakeManager(), memorymanager.NewFakeManager(), topologymanager.NewFakeManager()} -} - -func (cm *FakeContainerManager) GetPodCgroupRoot() string { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetPodCgroupRoot") - return "" -} - -func (cm *FakeContainerManager) GetDevices(_, _ string) []*podresourcesapi.ContainerDevices { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetDevices") - return nil -} - -func (cm *FakeContainerManager) GetAllocatableDevices() []*podresourcesapi.ContainerDevices { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetAllocatableDevices") - return nil -} - -func (cm *FakeContainerManager) ShouldResetExtendedResourceCapacity() bool { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "ShouldResetExtendedResourceCapacity") - return cm.shouldResetExtendedResourceCapacity -} - -func (cm *FakeContainerManager) GetAllocateResourcesPodAdmitHandler() lifecycle.PodAdmitHandler { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetAllocateResourcesPodAdmitHandler") - return topologymanager.NewFakeManager() -} - -func (cm *FakeContainerManager) UpdateAllocatedDevices() { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "UpdateAllocatedDevices") - return -} - -func (cm *FakeContainerManager) GetCPUs(_, _ string) []int64 { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetCPUs") - return nil -} - -func (cm *FakeContainerManager) GetAllocatableCPUs() []int64 { - cm.Lock() - defer cm.Unlock() - return nil -} - -func (cm *FakeContainerManager) GetMemory(_, _ string) []*podresourcesapi.ContainerMemory { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetMemory") - return nil -} - -func (cm *FakeContainerManager) GetAllocatableMemory() []*podresourcesapi.ContainerMemory { - cm.Lock() - defer cm.Unlock() - return nil -} - -func (cm *FakeContainerManager) GetDynamicResources(pod *v1.Pod, container *v1.Container) []*podresourcesapi.DynamicResource { - return nil -} - -func (cm *FakeContainerManager) GetNodeAllocatableAbsolute() v1.ResourceList { - cm.Lock() - defer cm.Unlock() - return nil -} - -func (cm *FakeContainerManager) PrepareDynamicResources(ctx context.Context, pod *v1.Pod) error { - return nil -} - -func (cm *FakeContainerManager) UnprepareDynamicResources(context.Context, *v1.Pod) error { - return nil -} - -func (cm *FakeContainerManager) PodMightNeedToUnprepareResources(UID types.UID) bool { - return false -} -func (cm *FakeContainerManager) UpdateAllocatedResourcesStatus(pod *v1.Pod, status *v1.PodStatus) { -} -func (cm *FakeContainerManager) Updates() <-chan resourceupdates.Update { - return nil -} - -func (cm *FakeContainerManager) PodHasExclusiveCPUs(pod *v1.Pod) bool { - return false -} - -func (cm *FakeContainerManager) ContainerHasExclusiveCPUs(pod *v1.Pod, container *v1.Container) bool { - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_internal_container_lifecycle.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_internal_container_lifecycle.go deleted file mode 100644 index d133f28f1..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_internal_container_lifecycle.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "k8s.io/api/core/v1" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" -) - -func NewFakeInternalContainerLifecycle() *fakeInternalContainerLifecycle { - return &fakeInternalContainerLifecycle{} -} - -type fakeInternalContainerLifecycle struct{} - -func (f *fakeInternalContainerLifecycle) PreCreateContainer(pod *v1.Pod, container *v1.Container, containerConfig *runtimeapi.ContainerConfig) error { - return nil -} - -func (f *fakeInternalContainerLifecycle) PreStartContainer(pod *v1.Pod, container *v1.Container, containerID string) error { - return nil -} - -func (f *fakeInternalContainerLifecycle) PostStopContainer(containerID string) error { - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_pod_container_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_pod_container_manager.go deleted file mode 100644 index c3ffae150..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/fake_pod_container_manager.go +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "reflect" - "sync" - - "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" -) - -type FakePodContainerManager struct { - sync.Mutex - CalledFunctions []string - Cgroups map[types.UID]CgroupName -} - -var _ PodContainerManager = &FakePodContainerManager{} - -func NewFakePodContainerManager() *FakePodContainerManager { - return &FakePodContainerManager{ - Cgroups: make(map[types.UID]CgroupName), - } -} - -func (m *FakePodContainerManager) AddPodFromCgroups(pod *kubecontainer.Pod) { - m.Lock() - defer m.Unlock() - m.Cgroups[pod.ID] = []string{pod.Name} -} - -func (m *FakePodContainerManager) Exists(_ *v1.Pod) bool { - m.Lock() - defer m.Unlock() - m.CalledFunctions = append(m.CalledFunctions, "Exists") - return true -} - -func (m *FakePodContainerManager) EnsureExists(_ *v1.Pod) error { - m.Lock() - defer m.Unlock() - m.CalledFunctions = append(m.CalledFunctions, "EnsureExists") - return nil -} - -func (m *FakePodContainerManager) GetPodContainerName(_ *v1.Pod) (CgroupName, string) { - m.Lock() - defer m.Unlock() - m.CalledFunctions = append(m.CalledFunctions, "GetPodContainerName") - return nil, "" -} - -func (m *FakePodContainerManager) Destroy(name CgroupName) error { - m.Lock() - defer m.Unlock() - m.CalledFunctions = append(m.CalledFunctions, "Destroy") - for key, cgname := range m.Cgroups { - if reflect.DeepEqual(cgname, name) { - delete(m.Cgroups, key) - return nil - } - } - return nil -} - -func (m *FakePodContainerManager) ReduceCPULimits(_ CgroupName) error { - m.Lock() - defer m.Unlock() - m.CalledFunctions = append(m.CalledFunctions, "ReduceCPULimits") - return nil -} - -func (m *FakePodContainerManager) GetAllPodsFromCgroups() (map[types.UID]CgroupName, error) { - m.Lock() - defer m.Unlock() - m.CalledFunctions = append(m.CalledFunctions, "GetAllPodsFromCgroups") - // return a copy for the race detector - grp := make(map[types.UID]CgroupName) - for key, value := range m.Cgroups { - grp[key] = value - } - return grp, nil -} - -func (m *FakePodContainerManager) IsPodCgroup(cgroupfs string) (bool, types.UID) { - m.Lock() - defer m.Unlock() - m.CalledFunctions = append(m.CalledFunctions, "IsPodCgroup") - return false, types.UID("") -} - -func (cm *FakePodContainerManager) GetPodCgroupMemoryUsage(_ *v1.Pod) (uint64, error) { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetPodCgroupMemoryUsage") - return 0, nil -} - -func (cm *FakePodContainerManager) GetPodCgroupConfig(_ *v1.Pod, _ v1.ResourceName) (*ResourceConfig, error) { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "GetPodCgroupConfig") - return nil, nil -} - -func (cm *FakePodContainerManager) SetPodCgroupConfig(pod *v1.Pod, resourceConfig *ResourceConfig) error { - cm.Lock() - defer cm.Unlock() - cm.CalledFunctions = append(cm.CalledFunctions, "SetPodCgroupConfig") - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go deleted file mode 100644 index 1de4f7d52..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "context" - - "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - internalapi "k8s.io/cri-api/pkg/apis" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - evictionapi "k8s.io/kubernetes/pkg/kubelet/eviction/api" -) - -// for typecheck across platforms -var _ func(int64, int64) int64 = MilliCPUToQuota -var _ func(int64) uint64 = MilliCPUToShares -var _ func(*v1.Pod, bool, uint64, bool) *ResourceConfig = ResourceConfigForPod -var _ func() (*CgroupSubsystems, error) = GetCgroupSubsystems -var _ func(string) ([]int, error) = getCgroupProcs -var _ func(types.UID) string = GetPodCgroupNameSuffix -var _ func(string, bool, string) string = NodeAllocatableRoot -var _ func(string) (string, error) = GetKubeletContainer - -// hardEvictionReservation returns a resourcelist that includes reservation of resources based on hard eviction thresholds. -func hardEvictionReservation(thresholds []evictionapi.Threshold, capacity v1.ResourceList) v1.ResourceList { - if len(thresholds) == 0 { - return nil - } - ret := v1.ResourceList{} - for _, threshold := range thresholds { - if threshold.Operator != evictionapi.OpLessThan { - continue - } - switch threshold.Signal { - case evictionapi.SignalMemoryAvailable: - memoryCapacity := capacity[v1.ResourceMemory] - value := evictionapi.GetThresholdQuantity(threshold.Value, &memoryCapacity) - ret[v1.ResourceMemory] = *value - case evictionapi.SignalNodeFsAvailable: - storageCapacity := capacity[v1.ResourceEphemeralStorage] - value := evictionapi.GetThresholdQuantity(threshold.Value, &storageCapacity) - ret[v1.ResourceEphemeralStorage] = *value - } - } - return ret -} - -func buildContainerMapAndRunningSetFromRuntime(ctx context.Context, runtimeService internalapi.RuntimeService) (containermap.ContainerMap, sets.Set[string]) { - podSandboxMap := make(map[string]string) - podSandboxList, _ := runtimeService.ListPodSandbox(ctx, nil) - for _, p := range podSandboxList { - podSandboxMap[p.Id] = p.Metadata.Uid - } - - runningSet := sets.New[string]() - containerMap := containermap.NewContainerMap() - containerList, _ := runtimeService.ListContainers(ctx, nil) - for _, c := range containerList { - if _, exists := podSandboxMap[c.PodSandboxId]; !exists { - klog.InfoS("No PodSandBox found for the container", "podSandboxId", c.PodSandboxId, "containerName", c.Metadata.Name, "containerId", c.Id) - continue - } - podUID := podSandboxMap[c.PodSandboxId] - containerMap.Add(podUID, c.Metadata.Name, c.Id) - if c.State == runtimeapi.ContainerState_CONTAINER_RUNNING { - klog.V(4).InfoS("Container reported running", "podSandboxId", c.PodSandboxId, "podUID", podUID, "containerName", c.Metadata.Name, "containerId", c.Id) - runningSet.Insert(c.Id) - } - } - return containerMap, runningSet -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go deleted file mode 100644 index 8e2ffd7d2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_linux.go +++ /dev/null @@ -1,343 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "bufio" - "fmt" - "os" - "path/filepath" - "strconv" - - libcontainercgroups "github.com/opencontainers/cgroups" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" - - "k8s.io/component-helpers/resource" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" - kubefeatures "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/cm/util" -) - -const ( - // These limits are defined in the kernel: - // https://github.com/torvalds/linux/blob/0bddd227f3dc55975e2b8dfa7fc6f959b062a2c7/kernel/sched/sched.h#L427-L428 - MinShares = 2 - MaxShares = 262144 - - SharesPerCPU = 1024 - MilliCPUToCPU = 1000 - - // 100000 microseconds is equivalent to 100ms - QuotaPeriod = 100000 - // 1000 microseconds is equivalent to 1ms - // defined here: - // https://github.com/torvalds/linux/blob/cac03ac368fabff0122853de2422d4e17a32de08/kernel/sched/core.c#L10546 - MinQuotaPeriod = 1000 - - // From the inverse of the conversion in MilliCPUToQuota: - // MinQuotaPeriod * MilliCPUToCPU / QuotaPeriod - MinMilliCPULimit = 10 -) - -// MilliCPUToQuota converts milliCPU to CFS quota and period values. -// Input parameters and resulting value is number of microseconds. -func MilliCPUToQuota(milliCPU int64, period int64) (quota int64) { - // CFS quota is measured in two values: - // - cfs_period_us=100ms (the amount of time to measure usage across given by period) - // - cfs_quota=20ms (the amount of cpu time allowed to be used across a period) - // so in the above example, you are limited to 20% of a single CPU - // for multi-cpu environments, you just scale equivalent amounts - // see https://www.kernel.org/doc/Documentation/scheduler/sched-bwc.txt for details - - if milliCPU == 0 { - return - } - - if !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.CPUCFSQuotaPeriod) { - period = QuotaPeriod - } - - // we then convert your milliCPU to a value normalized over a period - quota = (milliCPU * period) / MilliCPUToCPU - - // quota needs to be a minimum of 1ms. - if quota < MinQuotaPeriod { - quota = MinQuotaPeriod - } - return -} - -// MilliCPUToShares converts the milliCPU to CFS shares. -func MilliCPUToShares(milliCPU int64) uint64 { - if milliCPU == 0 { - // Docker converts zero milliCPU to unset, which maps to kernel default - // for unset: 1024. Return 2 here to really match kernel default for - // zero milliCPU. - return MinShares - } - // Conceptually (milliCPU / milliCPUToCPU) * sharesPerCPU, but factored to improve rounding. - shares := (milliCPU * SharesPerCPU) / MilliCPUToCPU - if shares < MinShares { - return MinShares - } - if shares > MaxShares { - return MaxShares - } - return uint64(shares) -} - -// HugePageLimits converts the API representation to a map -// from huge page size (in bytes) to huge page limit (in bytes). -func HugePageLimits(resourceList v1.ResourceList) map[int64]int64 { - hugePageLimits := map[int64]int64{} - for k, v := range resourceList { - if v1helper.IsHugePageResourceName(k) { - pageSize, _ := v1helper.HugePageSizeFromResourceName(k) - if value, exists := hugePageLimits[pageSize.Value()]; exists { - hugePageLimits[pageSize.Value()] = value + v.Value() - } else { - hugePageLimits[pageSize.Value()] = v.Value() - } - } - } - return hugePageLimits -} - -// ResourceConfigForPod takes the input pod and outputs the cgroup resource config. -func ResourceConfigForPod(allocatedPod *v1.Pod, enforceCPULimits bool, cpuPeriod uint64, enforceMemoryQoS bool) *ResourceConfig { - podLevelResourcesEnabled := utilfeature.DefaultFeatureGate.Enabled(kubefeatures.PodLevelResources) - // sum requests and limits. - reqs := resource.PodRequests(allocatedPod, resource.PodResourcesOptions{ - // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !podLevelResourcesEnabled, - UseStatusResources: false, - }) - // track if limits were applied for each resource. - memoryLimitsDeclared := true - cpuLimitsDeclared := true - - limits := resource.PodLimits(allocatedPod, resource.PodResourcesOptions{ - // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !podLevelResourcesEnabled, - ContainerFn: func(res v1.ResourceList, containerType resource.ContainerType) { - if res.Cpu().IsZero() { - cpuLimitsDeclared = false - } - if res.Memory().IsZero() { - memoryLimitsDeclared = false - } - }, - }) - - if podLevelResourcesEnabled && resource.IsPodLevelResourcesSet(allocatedPod) { - if !allocatedPod.Spec.Resources.Limits.Cpu().IsZero() { - cpuLimitsDeclared = true - } - - if !allocatedPod.Spec.Resources.Limits.Memory().IsZero() { - memoryLimitsDeclared = true - } - } - // map hugepage pagesize (bytes) to limits (bytes) - hugePageLimits := HugePageLimits(reqs) - - cpuRequests := int64(0) - cpuLimits := int64(0) - memoryLimits := int64(0) - if request, found := reqs[v1.ResourceCPU]; found { - cpuRequests = request.MilliValue() - } - if limit, found := limits[v1.ResourceCPU]; found { - cpuLimits = limit.MilliValue() - } - if limit, found := limits[v1.ResourceMemory]; found { - memoryLimits = limit.Value() - } - - // convert to CFS values - cpuShares := MilliCPUToShares(cpuRequests) - cpuQuota := MilliCPUToQuota(cpuLimits, int64(cpuPeriod)) - - // quota is not capped when cfs quota is disabled - if !enforceCPULimits { - cpuQuota = int64(-1) - } - - // determine the qos class - qosClass := v1qos.GetPodQOS(allocatedPod) - - // build the result - result := &ResourceConfig{} - if qosClass == v1.PodQOSGuaranteed { - result.CPUShares = &cpuShares - result.CPUQuota = &cpuQuota - result.CPUPeriod = &cpuPeriod - result.Memory = &memoryLimits - } else if qosClass == v1.PodQOSBurstable { - result.CPUShares = &cpuShares - if cpuLimitsDeclared { - result.CPUQuota = &cpuQuota - result.CPUPeriod = &cpuPeriod - } - if memoryLimitsDeclared { - result.Memory = &memoryLimits - } - } else { - shares := uint64(MinShares) - result.CPUShares = &shares - } - result.HugePageLimit = hugePageLimits - - if enforceMemoryQoS { - memoryMin := int64(0) - if request, found := reqs[v1.ResourceMemory]; found { - memoryMin = request.Value() - } - if memoryMin > 0 { - result.Unified = map[string]string{ - Cgroup2MemoryMin: strconv.FormatInt(memoryMin, 10), - } - } - } - - return result -} - -// getCgroupSubsystemsV1 returns information about the mounted cgroup v1 subsystems -func getCgroupSubsystemsV1() (*CgroupSubsystems, error) { - // get all cgroup mounts. - allCgroups, err := libcontainercgroups.GetCgroupMounts(true) - if err != nil { - return &CgroupSubsystems{}, err - } - if len(allCgroups) == 0 { - return &CgroupSubsystems{}, fmt.Errorf("failed to find cgroup mounts") - } - mountPoints := make(map[string]string, len(allCgroups)) - for _, mount := range allCgroups { - // BEFORE kubelet used a random mount point per cgroups subsystem; - // NOW more deterministic: kubelet use mount point with shortest path; - // FUTURE is bright with clear expectation determined in doc. - // ref. issue: https://github.com/kubernetes/kubernetes/issues/95488 - - for _, subsystem := range mount.Subsystems { - previous := mountPoints[subsystem] - if previous == "" || len(mount.Mountpoint) < len(previous) { - mountPoints[subsystem] = mount.Mountpoint - } - } - } - return &CgroupSubsystems{ - Mounts: allCgroups, - MountPoints: mountPoints, - }, nil -} - -// getCgroupSubsystemsV2 returns information about the enabled cgroup v2 subsystems -func getCgroupSubsystemsV2() (*CgroupSubsystems, error) { - controllers, err := libcontainercgroups.GetAllSubsystems() - if err != nil { - return nil, err - } - - mounts := []libcontainercgroups.Mount{} - mountPoints := make(map[string]string, len(controllers)) - for _, controller := range controllers { - mountPoints[controller] = util.CgroupRoot - m := libcontainercgroups.Mount{ - Mountpoint: util.CgroupRoot, - Root: util.CgroupRoot, - Subsystems: []string{controller}, - } - mounts = append(mounts, m) - } - - return &CgroupSubsystems{ - Mounts: mounts, - MountPoints: mountPoints, - }, nil -} - -// GetCgroupSubsystems returns information about the mounted cgroup subsystems -func GetCgroupSubsystems() (*CgroupSubsystems, error) { - if libcontainercgroups.IsCgroup2UnifiedMode() { - return getCgroupSubsystemsV2() - } - - return getCgroupSubsystemsV1() -} - -// getCgroupProcs takes a cgroup directory name as an argument -// reads through the cgroup's procs file and returns a list of tgid's. -// It returns an empty list if a procs file doesn't exists -func getCgroupProcs(dir string) ([]int, error) { - procsFile := filepath.Join(dir, "cgroup.procs") - f, err := os.Open(procsFile) - if err != nil { - if os.IsNotExist(err) { - // The procsFile does not exist, So no pids attached to this directory - return []int{}, nil - } - return nil, err - } - defer f.Close() - - s := bufio.NewScanner(f) - out := []int{} - for s.Scan() { - if t := s.Text(); t != "" { - pid, err := strconv.Atoi(t) - if err != nil { - return nil, fmt.Errorf("unexpected line in %v; could not convert to pid: %v", procsFile, err) - } - out = append(out, pid) - } - } - return out, nil -} - -// GetPodCgroupNameSuffix returns the last element of the pod CgroupName identifier -func GetPodCgroupNameSuffix(podUID types.UID) string { - return podCgroupNamePrefix + string(podUID) -} - -// NodeAllocatableRoot returns the literal cgroup path for the node allocatable cgroup -func NodeAllocatableRoot(cgroupRoot string, cgroupsPerQOS bool, cgroupDriver string) string { - nodeAllocatableRoot := ParseCgroupfsToCgroupName(cgroupRoot) - if cgroupsPerQOS { - nodeAllocatableRoot = NewCgroupName(nodeAllocatableRoot, defaultNodeAllocatableCgroupName) - } - if cgroupDriver == "systemd" { - return nodeAllocatableRoot.ToSystemd() - } - return nodeAllocatableRoot.ToCgroupfs() -} - -// GetKubeletContainer returns the cgroup the kubelet will use -func GetKubeletContainer(kubeletCgroups string) (string, error) { - if kubeletCgroups == "" { - cont, err := getContainer(os.Getpid()) - if err != nil { - return "", err - } - return cont, nil - } - return kubeletCgroups, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go deleted file mode 100644 index 34d4ee59d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/helpers_unsupported.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build !linux -// +build !linux - -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -const ( - MinShares = 0 - MaxShares = 0 - - SharesPerCPU = 0 - MilliCPUToCPU = 0 - - QuotaPeriod = 0 - MinQuotaPeriod = 0 - MinMilliCPULimit = 0 -) - -// MilliCPUToQuota converts milliCPU and period to CFS quota values. -func MilliCPUToQuota(milliCPU, period int64) int64 { - return 0 -} - -// MilliCPUToShares converts the milliCPU to CFS shares. -func MilliCPUToShares(milliCPU int64) uint64 { - return 0 -} - -// ResourceConfigForPod takes the input pod and outputs the cgroup resource config. -func ResourceConfigForPod(pod *v1.Pod, enforceCPULimit bool, cpuPeriod uint64, enforceMemoryQoS bool) *ResourceConfig { - return nil -} - -// GetCgroupSubsystems returns information about the mounted cgroup subsystems -func GetCgroupSubsystems() (*CgroupSubsystems, error) { - return nil, nil -} - -func getCgroupProcs(dir string) ([]int, error) { - return nil, nil -} - -// GetPodCgroupNameSuffix returns the last element of the pod CgroupName identifier -func GetPodCgroupNameSuffix(podUID types.UID) string { - return "" -} - -// NodeAllocatableRoot returns the literal cgroup path for the node allocatable cgroup -func NodeAllocatableRoot(cgroupRoot string, cgroupsPerQOS bool, cgroupDriver string) string { - return "" -} - -// GetKubeletContainer returns the cgroup the kubelet will use -func GetKubeletContainer(kubeletCgroups string) (string, error) { - return "", nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle.go deleted file mode 100644 index 5e50fd166..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle.go +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "k8s.io/api/core/v1" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/kubernetes/pkg/kubelet/cm/cpumanager" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" -) - -type InternalContainerLifecycle interface { - PreCreateContainer(pod *v1.Pod, container *v1.Container, containerConfig *runtimeapi.ContainerConfig) error - PreStartContainer(pod *v1.Pod, container *v1.Container, containerID string) error - PostStopContainer(containerID string) error -} - -// Implements InternalContainerLifecycle interface. -type internalContainerLifecycleImpl struct { - cpuManager cpumanager.Manager - memoryManager memorymanager.Manager - topologyManager topologymanager.Manager -} - -func (i *internalContainerLifecycleImpl) PreStartContainer(pod *v1.Pod, container *v1.Container, containerID string) error { - if i.cpuManager != nil { - i.cpuManager.AddContainer(pod, container, containerID) - } - - if i.memoryManager != nil { - i.memoryManager.AddContainer(pod, container, containerID) - } - - i.topologyManager.AddContainer(pod, container, containerID) - - return nil -} - -func (i *internalContainerLifecycleImpl) PostStopContainer(containerID string) error { - return i.topologyManager.RemoveContainer(containerID) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go deleted file mode 100644 index 0c3bb2e49..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_linux.go +++ /dev/null @@ -1,51 +0,0 @@ -//go:build linux -// +build linux - -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "strconv" - "strings" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" -) - -func (i *internalContainerLifecycleImpl) PreCreateContainer(pod *v1.Pod, container *v1.Container, containerConfig *runtimeapi.ContainerConfig) error { - if i.cpuManager != nil { - allocatedCPUs := i.cpuManager.GetCPUAffinity(string(pod.UID), container.Name) - if !allocatedCPUs.IsEmpty() { - containerConfig.Linux.Resources.CpusetCpus = allocatedCPUs.String() - } - } - - if i.memoryManager != nil { - numaNodes := i.memoryManager.GetMemoryNUMANodes(pod, container) - if numaNodes.Len() > 0 { - var affinity []string - for _, numaNode := range sets.List(numaNodes) { - affinity = append(affinity, strconv.Itoa(numaNode)) - } - containerConfig.Linux.Resources.CpusetMems = strings.Join(affinity, ",") - } - } - - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go deleted file mode 100644 index 5028c40bb..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_unsupported.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build !linux && !windows -// +build !linux,!windows - -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "k8s.io/api/core/v1" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" -) - -func (i *internalContainerLifecycleImpl) PreCreateContainer(pod *v1.Pod, container *v1.Container, containerConfig *runtimeapi.ContainerConfig) error { - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go deleted file mode 100644 index 939658d84..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/internal_container_lifecycle_windows.go +++ /dev/null @@ -1,141 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/klog/v2" - kubefeatures "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/winstats" - "k8s.io/utils/cpuset" -) - -func (i *internalContainerLifecycleImpl) PreCreateContainer(pod *v1.Pod, container *v1.Container, containerConfig *runtimeapi.ContainerConfig) error { - if !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.WindowsCPUAndMemoryAffinity) { - return nil - } - - klog.V(4).Info("PreCreateContainer for Windows") - - // retrieve CPU and NUMA affinity from CPU Manager and Memory Manager (if enabled) - var allocatedCPUs cpuset.CPUSet - if i.cpuManager != nil { - allocatedCPUs = i.cpuManager.GetCPUAffinity(string(pod.UID), container.Name) - } - - var numaNodes sets.Set[int] - if i.memoryManager != nil { - numaNodes = i.memoryManager.GetMemoryNUMANodes(pod, container) - } - - // Gather all CPUs associated with the selected NUMA nodes - var allNumaNodeCPUs []winstats.GroupAffinity - for _, numaNode := range sets.List(numaNodes) { - affinity, err := winstats.GetCPUsforNUMANode(uint16(numaNode)) - if err != nil { - return fmt.Errorf("failed to get CPUs for NUMA node %d: %v", numaNode, err) - } - allNumaNodeCPUs = append(allNumaNodeCPUs, *affinity) - } - - var finalCPUSet = computeFinalCpuSet(allocatedCPUs, allNumaNodeCPUs) - - klog.V(4).InfoS("Setting CPU affinity", "affinity", finalCPUSet, "container", container.Name, "pod", pod.UID) - - // Set CPU group affinities in the container config - if finalCPUSet != nil { - var cpusToGroupAffinities []*runtimeapi.WindowsCpuGroupAffinity - for group, mask := range groupMasks(finalCPUSet) { - - cpusToGroupAffinities = append(cpusToGroupAffinities, &runtimeapi.WindowsCpuGroupAffinity{ - CpuGroup: uint32(group), - CpuMask: uint64(mask), - }) - } - containerConfig.Windows.Resources.AffinityCpus = cpusToGroupAffinities - } - - // return nil if no CPUs were selected - return nil -} - -// computeFinalCpuSet determines the final set of CPUs to use based on the CPU and memory managers -// and is extracted so that it can be tested -func computeFinalCpuSet(allocatedCPUs cpuset.CPUSet, allNumaNodeCPUs []winstats.GroupAffinity) sets.Set[int] { - if !allocatedCPUs.IsEmpty() && len(allNumaNodeCPUs) > 0 { - // Both CPU and memory managers are enabled - - numaNodeAffinityCPUSet := computeCPUSet(allNumaNodeCPUs) - cpuManagerAffinityCPUSet := sets.New[int](allocatedCPUs.List()...) - - // Determine which set of CPUs to use using the following logic outlined in the KEP: - // Case 1: CPU manager selects more CPUs than those available in the NUMA nodes selected by the memory manager - // Case 2: CPU manager selects fewer CPUs, and they all fall within the CPUs available in the NUMA nodes selected by the memory manager - // Case 3: CPU manager selects fewer CPUs, but some are outside of the CPUs available in the NUMA nodes selected by the memory manager - - if cpuManagerAffinityCPUSet.Len() > numaNodeAffinityCPUSet.Len() { - // Case 1, use CPU manager selected CPUs - return cpuManagerAffinityCPUSet - } else if numaNodeAffinityCPUSet.IsSuperset(cpuManagerAffinityCPUSet) { - // case 2, use CPU manager selected CPUstry - return cpuManagerAffinityCPUSet - } else { - // Case 3, merge CPU manager and memory manager selected CPUs - return cpuManagerAffinityCPUSet.Union(numaNodeAffinityCPUSet) - } - } else if !allocatedCPUs.IsEmpty() { - // Only CPU manager is enabled, use CPU manager selected CPUs - return sets.New[int](allocatedCPUs.List()...) - } else if len(allNumaNodeCPUs) > 0 { - // Only memory manager is enabled, use CPUs associated with selected NUMA nodes - return computeCPUSet(allNumaNodeCPUs) - } - return nil -} - -// computeCPUSet converts a list of GroupAffinity to a set of CPU IDs -func computeCPUSet(affinities []winstats.GroupAffinity) sets.Set[int] { - cpuSet := sets.New[int]() - for _, affinity := range affinities { - for i := 0; i < 64; i++ { - if (affinity.Mask>>i)&1 == 1 { - cpuID := int(affinity.Group)*64 + i - cpuSet.Insert(cpuID) - } - } - } - return cpuSet -} - -// groupMasks converts a set of CPU IDs into group and mask representations -func groupMasks(cpuSet sets.Set[int]) map[int]uint64 { - groupMasks := make(map[int]uint64) - for cpu := range cpuSet { - group := cpu / 64 - mask := uint64(1) << (cpu % 64) - groupMasks[group] |= mask - } - return groupMasks -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go deleted file mode 100644 index 46874e500..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/fake_memory_manager.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package memorymanager - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/config" - "k8s.io/kubernetes/pkg/kubelet/status" -) - -type fakeManager struct { - state state.State -} - -func (m *fakeManager) Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, podStatusProvider status.PodStatusProvider, containerRuntime runtimeService, initialContainers containermap.ContainerMap) error { - klog.InfoS("Start()") - return nil -} - -func (m *fakeManager) Policy() Policy { - klog.InfoS("Policy()") - return NewPolicyNone() -} - -func (m *fakeManager) Allocate(pod *v1.Pod, container *v1.Container) error { - klog.InfoS("Allocate", "pod", klog.KObj(pod), "containerName", container.Name) - return nil -} - -func (m *fakeManager) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) { - klog.InfoS("Add container", "pod", klog.KObj(pod), "containerName", container.Name, "containerID", containerID) -} - -func (m *fakeManager) GetMemoryNUMANodes(pod *v1.Pod, container *v1.Container) sets.Set[int] { - klog.InfoS("Get MemoryNUMANodes", "pod", klog.KObj(pod), "containerName", container.Name) - return nil -} - -func (m *fakeManager) RemoveContainer(containerID string) error { - klog.InfoS("RemoveContainer", "containerID", containerID) - return nil -} - -func (m *fakeManager) GetTopologyHints(pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - klog.InfoS("Get Topology Hints", "pod", klog.KObj(pod), "containerName", container.Name) - return map[string][]topologymanager.TopologyHint{} -} - -func (m *fakeManager) GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint { - klog.InfoS("Get Pod Topology Hints", "pod", klog.KObj(pod)) - return map[string][]topologymanager.TopologyHint{} -} - -func (m *fakeManager) State() state.Reader { - return m.state -} - -// GetAllocatableMemory returns the amount of allocatable memory for each NUMA node -func (m *fakeManager) GetAllocatableMemory() []state.Block { - klog.InfoS("Get Allocatable Memory") - return []state.Block{} -} - -// GetMemory returns the memory allocated by a container from NUMA nodes -func (m *fakeManager) GetMemory(podUID, containerName string) []state.Block { - klog.InfoS("Get Memory", "podUID", podUID, "containerName", containerName) - return []state.Block{} -} - -// NewFakeManager creates empty/fake memory manager -func NewFakeManager() Manager { - return &fakeManager{ - state: state.NewMemoryState(), - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go deleted file mode 100644 index 448539fc0..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/memory_manager.go +++ /dev/null @@ -1,468 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package memorymanager - -import ( - "context" - "fmt" - "runtime" - "sync" - - cadvisorapi "github.com/google/cadvisor/info/v1" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/util/sets" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/klog/v2" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - corev1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/config" - "k8s.io/kubernetes/pkg/kubelet/status" -) - -// memoryManagerStateFileName is the file name where memory manager stores its state -const memoryManagerStateFileName = "memory_manager_state" - -// ActivePodsFunc is a function that returns a list of active pods -type ActivePodsFunc func() []*v1.Pod - -type runtimeService interface { - UpdateContainerResources(ctx context.Context, id string, resources *runtimeapi.ContainerResources) error -} - -type sourcesReadyStub struct{} - -func (s *sourcesReadyStub) AddSource(source string) {} -func (s *sourcesReadyStub) AllReady() bool { return true } - -// Manager interface provides methods for Kubelet to manage pod memory. -type Manager interface { - // Start is called during Kubelet initialization. - Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, podStatusProvider status.PodStatusProvider, containerRuntime runtimeService, initialContainers containermap.ContainerMap) error - - // AddContainer adds the mapping between container ID to pod UID and the container name - // The mapping used to remove the memory allocation during the container removal - AddContainer(p *v1.Pod, c *v1.Container, containerID string) - - // Allocate is called to pre-allocate memory resources during Pod admission. - // This must be called at some point prior to the AddContainer() call for a container, e.g. at pod admission time. - Allocate(pod *v1.Pod, container *v1.Container) error - - // RemoveContainer is called after Kubelet decides to kill or delete a - // container. After this call, any memory allocated to the container is freed. - RemoveContainer(containerID string) error - - // State returns a read-only interface to the internal memory manager state. - State() state.Reader - - // GetTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment among this - // and other resource controllers. - GetTopologyHints(*v1.Pod, *v1.Container) map[string][]topologymanager.TopologyHint - - // GetPodTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment among this - // and other resource controllers. - GetPodTopologyHints(*v1.Pod) map[string][]topologymanager.TopologyHint - - // GetMemoryNUMANodes provides NUMA nodes that are used to allocate the container memory - GetMemoryNUMANodes(pod *v1.Pod, container *v1.Container) sets.Set[int] - - // GetAllocatableMemory returns the amount of allocatable memory for each NUMA node - GetAllocatableMemory() []state.Block - - // GetMemory returns the memory allocated by a container from NUMA nodes - GetMemory(podUID, containerName string) []state.Block -} - -type manager struct { - sync.Mutex - policy Policy - - // state allows to restore information regarding memory allocation for guaranteed pods - // in the case of the kubelet restart - state state.State - - // containerRuntime is the container runtime service interface needed - // to make UpdateContainerResources() calls against the containers. - containerRuntime runtimeService - - // activePods is a method for listing active pods on the node - // so all the containers can be updated during call to the removeStaleState. - activePods ActivePodsFunc - - // podStatusProvider provides a method for obtaining pod statuses - // and the containerID of their containers - podStatusProvider status.PodStatusProvider - - // containerMap provides a mapping from (pod, container) -> containerID - // for all containers a pod - containerMap containermap.ContainerMap - - // sourcesReady provides the readiness of kubelet configuration sources such as apiserver update readiness. - // We use it to determine when we can purge inactive pods from checkpointed state. - sourcesReady config.SourcesReady - - // stateFileDirectory holds the directory where the state file for checkpoints is held. - stateFileDirectory string - - // allocatableMemory holds the allocatable memory for each NUMA node - allocatableMemory []state.Block -} - -var _ Manager = &manager{} - -// NewManager returns new instance of the memory manager -func NewManager(policyName string, machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory []kubeletconfig.MemoryReservation, stateFileDirectory string, affinity topologymanager.Store) (Manager, error) { - var policy Policy - - switch policyType(policyName) { - - case policyTypeNone: - policy = NewPolicyNone() - - case policyTypeStatic: - if runtime.GOOS == "windows" { - return nil, fmt.Errorf("policy %q is not available on Windows", policyTypeStatic) - } - - systemReserved, err := getSystemReservedMemory(machineInfo, nodeAllocatableReservation, reservedMemory) - if err != nil { - return nil, err - } - - policy, err = NewPolicyStatic(machineInfo, systemReserved, affinity) - if err != nil { - return nil, err - } - - case policyTypeBestEffort: - if runtime.GOOS == "windows" { - systemReserved, err := getSystemReservedMemory(machineInfo, nodeAllocatableReservation, reservedMemory) - if err != nil { - return nil, err - } - policy, err = NewPolicyBestEffort(machineInfo, systemReserved, affinity) - if err != nil { - return nil, err - } - } else { - return nil, fmt.Errorf("policy %q is not available for platform %q", policyTypeBestEffort, runtime.GOOS) - } - - default: - return nil, fmt.Errorf("unknown policy: %q", policyName) - } - - manager := &manager{ - policy: policy, - stateFileDirectory: stateFileDirectory, - } - manager.sourcesReady = &sourcesReadyStub{} - return manager, nil -} - -// Start starts the memory manager under the kubelet and calls policy start -func (m *manager) Start(activePods ActivePodsFunc, sourcesReady config.SourcesReady, podStatusProvider status.PodStatusProvider, containerRuntime runtimeService, initialContainers containermap.ContainerMap) error { - klog.InfoS("Starting memorymanager", "policy", m.policy.Name()) - m.sourcesReady = sourcesReady - m.activePods = activePods - m.podStatusProvider = podStatusProvider - m.containerRuntime = containerRuntime - m.containerMap = initialContainers - - stateImpl, err := state.NewCheckpointState(m.stateFileDirectory, memoryManagerStateFileName, m.policy.Name()) - if err != nil { - klog.ErrorS(err, "Could not initialize checkpoint manager, please drain node and remove policy state file") - return err - } - m.state = stateImpl - - err = m.policy.Start(m.state) - if err != nil { - klog.ErrorS(err, "Policy start error") - return err - } - - m.allocatableMemory = m.policy.GetAllocatableMemory(m.state) - - klog.V(4).InfoS("memorymanager started", "policy", m.policy.Name()) - return nil -} - -// AddContainer saves the value of requested memory for the guaranteed pod under the state and set memory affinity according to the topolgy manager -func (m *manager) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) { - m.Lock() - defer m.Unlock() - - m.containerMap.Add(string(pod.UID), container.Name, containerID) - - // Since we know that each init container always runs to completion before - // the next container starts, we can safely remove references to any previously - // started init containers. This will free up the memory from these init containers - // for use in other pods. If the current container happens to be an init container, - // we skip deletion of it until the next container is added, and this is called again. - for _, initContainer := range pod.Spec.InitContainers { - if initContainer.Name == container.Name { - break - } - - // Since a restartable init container remains running for the full - // duration of the pod's lifecycle, we should not remove it from the - // memory manager state. - if podutil.IsRestartableInitContainer(&initContainer) { - continue - } - - m.policyRemoveContainerByRef(string(pod.UID), initContainer.Name) - } -} - -// GetMemoryNUMANodes provides NUMA nodes that used to allocate the container memory -func (m *manager) GetMemoryNUMANodes(pod *v1.Pod, container *v1.Container) sets.Set[int] { - // Get NUMA node affinity of blocks assigned to the container during Allocate() - numaNodes := sets.New[int]() - for _, block := range m.state.GetMemoryBlocks(string(pod.UID), container.Name) { - for _, nodeID := range block.NUMAAffinity { - // avoid nodes duplication when hugepages and memory blocks pinned to the same NUMA node - numaNodes.Insert(nodeID) - } - } - - if numaNodes.Len() == 0 { - klog.V(5).InfoS("NUMA nodes not available for allocation", "pod", klog.KObj(pod), "containerName", container.Name) - return nil - } - - klog.InfoS("Memory affinity", "pod", klog.KObj(pod), "containerName", container.Name, "numaNodes", numaNodes) - return numaNodes -} - -// Allocate is called to pre-allocate memory resources during Pod admission. -func (m *manager) Allocate(pod *v1.Pod, container *v1.Container) error { - // Garbage collect any stranded resources before allocation - m.removeStaleState() - - m.Lock() - defer m.Unlock() - - // Call down into the policy to assign this container memory if required. - if err := m.policy.Allocate(m.state, pod, container); err != nil { - klog.ErrorS(err, "Allocate error", "pod", klog.KObj(pod), "containerName", container.Name) - return err - } - return nil -} - -// RemoveContainer removes the container from the state -func (m *manager) RemoveContainer(containerID string) error { - m.Lock() - defer m.Unlock() - - // if error appears it means container entry already does not exist under the container map - podUID, containerName, err := m.containerMap.GetContainerRef(containerID) - if err != nil { - klog.ErrorS(err, "Failed to get container from container map", "containerID", containerID) - return nil - } - - m.policyRemoveContainerByRef(podUID, containerName) - - return nil -} - -// State returns the state of the manager -func (m *manager) State() state.Reader { - return m.state -} - -// GetPodTopologyHints returns the topology hints for the topology manager -func (m *manager) GetPodTopologyHints(pod *v1.Pod) map[string][]topologymanager.TopologyHint { - // Garbage collect any stranded resources before providing TopologyHints - m.removeStaleState() - // Delegate to active policy - return m.policy.GetPodTopologyHints(m.state, pod) -} - -// GetTopologyHints returns the topology hints for the topology manager -func (m *manager) GetTopologyHints(pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - // Garbage collect any stranded resources before providing TopologyHints - m.removeStaleState() - // Delegate to active policy - return m.policy.GetTopologyHints(m.state, pod, container) -} - -// TODO: move the method to the upper level, to re-use it under the CPU and memory managers -func (m *manager) removeStaleState() { - // Only once all sources are ready do we attempt to remove any stale state. - // This ensures that the call to `m.activePods()` below will succeed with - // the actual active pods list. - if !m.sourcesReady.AllReady() { - return - } - - // We grab the lock to ensure that no new containers will grab memory block while - // executing the code below. Without this lock, its possible that we end up - // removing state that is newly added by an asynchronous call to - // AddContainer() during the execution of this code. - m.Lock() - defer m.Unlock() - - // Get the list of active pods. - activePods := m.activePods() - - // Build a list of (podUID, containerName) pairs for all containers in all active Pods. - activeContainers := make(map[string]map[string]struct{}) - for _, pod := range activePods { - activeContainers[string(pod.UID)] = make(map[string]struct{}) - for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { - activeContainers[string(pod.UID)][container.Name] = struct{}{} - } - } - - // Loop through the MemoryManager state. Remove any state for containers not - // in the `activeContainers` list built above. - assignments := m.state.GetMemoryAssignments() - for podUID := range assignments { - for containerName := range assignments[podUID] { - if _, ok := activeContainers[podUID][containerName]; !ok { - klog.V(2).InfoS("RemoveStaleState removing state", "podUID", podUID, "containerName", containerName) - m.policyRemoveContainerByRef(podUID, containerName) - } - } - } - - m.containerMap.Visit(func(podUID, containerName, containerID string) { - if _, ok := activeContainers[podUID][containerName]; !ok { - klog.V(2).InfoS("RemoveStaleState removing state", "podUID", podUID, "containerName", containerName) - m.policyRemoveContainerByRef(podUID, containerName) - } - }) -} - -func (m *manager) policyRemoveContainerByRef(podUID string, containerName string) { - m.policy.RemoveContainer(m.state, podUID, containerName) - m.containerMap.RemoveByContainerRef(podUID, containerName) -} - -func getTotalMemoryTypeReserved(machineInfo *cadvisorapi.MachineInfo, reservedMemory []kubeletconfig.MemoryReservation) (map[v1.ResourceName]resource.Quantity, error) { - totalMemoryType := map[v1.ResourceName]resource.Quantity{} - - numaNodes := map[int]bool{} - for _, numaNode := range machineInfo.Topology { - numaNodes[numaNode.Id] = true - } - - for _, reservation := range reservedMemory { - if !numaNodes[int(reservation.NumaNode)] { - return nil, fmt.Errorf("the reserved memory configuration references a NUMA node %d that does not exist on this machine", reservation.NumaNode) - } - - for resourceName, q := range reservation.Limits { - if value, ok := totalMemoryType[resourceName]; ok { - q.Add(value) - } - totalMemoryType[resourceName] = q - } - } - - return totalMemoryType, nil -} - -func validateReservedMemory(machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory []kubeletconfig.MemoryReservation) error { - totalMemoryType, err := getTotalMemoryTypeReserved(machineInfo, reservedMemory) - if err != nil { - return err - } - - commonMemoryTypeSet := make(map[v1.ResourceName]bool) - for resourceType := range totalMemoryType { - commonMemoryTypeSet[resourceType] = true - } - - for resourceType := range nodeAllocatableReservation { - if !(corev1helper.IsHugePageResourceName(resourceType) || resourceType == v1.ResourceMemory) { - continue - } - commonMemoryTypeSet[resourceType] = true - } - - for resourceType := range commonMemoryTypeSet { - nodeAllocatableMemory := resource.NewQuantity(0, resource.DecimalSI) - if memValue, set := nodeAllocatableReservation[resourceType]; set { - nodeAllocatableMemory.Add(memValue) - } - - reservedMemory := resource.NewQuantity(0, resource.DecimalSI) - if memValue, set := totalMemoryType[resourceType]; set { - reservedMemory.Add(memValue) - } - - if !(*nodeAllocatableMemory).Equal(*reservedMemory) { - return fmt.Errorf("the total amount %q of type %q is not equal to the value %q determined by Node Allocatable feature", reservedMemory.String(), resourceType, nodeAllocatableMemory.String()) - } - } - - return nil -} - -func convertReserved(machineInfo *cadvisorapi.MachineInfo, reservedMemory []kubeletconfig.MemoryReservation) (systemReservedMemory, error) { - reservedMemoryConverted := make(map[int]map[v1.ResourceName]uint64) - for _, node := range machineInfo.Topology { - reservedMemoryConverted[node.Id] = make(map[v1.ResourceName]uint64) - } - - for _, reservation := range reservedMemory { - for resourceName, q := range reservation.Limits { - val, success := q.AsInt64() - if !success { - return nil, fmt.Errorf("could not covert a variable of type Quantity to int64") - } - reservedMemoryConverted[int(reservation.NumaNode)][resourceName] = uint64(val) - } - } - - return reservedMemoryConverted, nil -} - -func getSystemReservedMemory(machineInfo *cadvisorapi.MachineInfo, nodeAllocatableReservation v1.ResourceList, reservedMemory []kubeletconfig.MemoryReservation) (systemReservedMemory, error) { - if err := validateReservedMemory(machineInfo, nodeAllocatableReservation, reservedMemory); err != nil { - return nil, err - } - - reservedMemoryConverted, err := convertReserved(machineInfo, reservedMemory) - if err != nil { - return nil, err - } - - return reservedMemoryConverted, nil -} - -// GetAllocatableMemory returns the amount of allocatable memory for each NUMA node -func (m *manager) GetAllocatableMemory() []state.Block { - return m.allocatableMemory -} - -// GetMemory returns the memory allocated by a container from NUMA nodes -func (m *manager) GetMemory(podUID, containerName string) []state.Block { - return m.state.GetMemoryBlocks(podUID, containerName) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go deleted file mode 100644 index a65a90dca..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package memorymanager - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" -) - -// Type defines the policy type -type policyType string - -// Policy implements logic for pod container to a memory assignment. -type Policy interface { - Name() string - Start(s state.State) error - // Allocate call is idempotent - Allocate(s state.State, pod *v1.Pod, container *v1.Container) error - // RemoveContainer call is idempotent - RemoveContainer(s state.State, podUID string, containerName string) - // GetTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment among this - // and other resource controllers. - GetTopologyHints(s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint - // GetPodTopologyHints implements the topologymanager.HintProvider Interface - // and is consulted to achieve NUMA aware resource alignment among this - // and other resource controllers. - GetPodTopologyHints(s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint - // GetAllocatableMemory returns the amount of allocatable memory for each NUMA node - GetAllocatableMemory(s state.State) []state.Block -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go deleted file mode 100644 index 2a2eabc82..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_best_effort.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package memorymanager - -import ( - cadvisorapi "github.com/google/cadvisor/info/v1" - - v1 "k8s.io/api/core/v1" - - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" -) - -// On Windows we want to use the same logic as the StaticPolicy to compute the memory topology hints -// but unlike linux based systems, on Windows systems numa nodes cannot be directly assigned or guaranteed via Windows APIs -// (windows scheduler will use the numa node that is closest to the cpu assigned therefor respecting the numa node assignment as a best effort). Because of this we don't want to have users specify "StaticPolicy" for the memory manager -// policy via kubelet configuration. Instead we want to use the "BestEffort" policy which will use the same logic as the StaticPolicy -// and doing so will reduce code duplication. -const policyTypeBestEffort policyType = "BestEffort" - -// bestEffortPolicy is implementation of the policy interface for the BestEffort policy -type bestEffortPolicy struct { - static *staticPolicy -} - -var _ Policy = &bestEffortPolicy{} - -func NewPolicyBestEffort(machineInfo *cadvisorapi.MachineInfo, reserved systemReservedMemory, affinity topologymanager.Store) (Policy, error) { - p, err := NewPolicyStatic(machineInfo, reserved, affinity) - - if err != nil { - return nil, err - } - - return &bestEffortPolicy{ - static: p.(*staticPolicy), - }, nil -} - -func (p *bestEffortPolicy) Name() string { - return string(policyTypeBestEffort) -} - -func (p *bestEffortPolicy) Start(s state.State) error { - return p.static.Start(s) -} - -func (p *bestEffortPolicy) Allocate(s state.State, pod *v1.Pod, container *v1.Container) (rerr error) { - return p.static.Allocate(s, pod, container) -} - -func (p *bestEffortPolicy) RemoveContainer(s state.State, podUID string, containerName string) { - p.static.RemoveContainer(s, podUID, containerName) -} - -func (p *bestEffortPolicy) GetPodTopologyHints(s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint { - return p.static.GetPodTopologyHints(s, pod) -} - -func (p *bestEffortPolicy) GetTopologyHints(s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - return p.static.GetTopologyHints(s, pod, container) -} - -func (p *bestEffortPolicy) GetAllocatableMemory(s state.State) []state.Block { - return p.static.GetAllocatableMemory(s) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go deleted file mode 100644 index 5bb52db7e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_none.go +++ /dev/null @@ -1,72 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package memorymanager - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" -) - -const policyTypeNone policyType = "None" - -// none is implementation of the policy interface for the none policy, using none -// policy is the same as disable memory management -type none struct{} - -var _ Policy = &none{} - -// NewPolicyNone returns new none policy instance -func NewPolicyNone() Policy { - return &none{} -} - -func (p *none) Name() string { - return string(policyTypeNone) -} - -func (p *none) Start(s state.State) error { - return nil -} - -// Allocate call is idempotent -func (p *none) Allocate(s state.State, pod *v1.Pod, container *v1.Container) error { - return nil -} - -// RemoveContainer call is idempotent -func (p *none) RemoveContainer(s state.State, podUID string, containerName string) { -} - -// GetTopologyHints implements the topologymanager.HintProvider Interface -// and is consulted to achieve NUMA aware resource alignment among this -// and other resource controllers. -func (p *none) GetTopologyHints(s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - return nil -} - -// GetPodTopologyHints implements the topologymanager.HintProvider Interface -// and is consulted to achieve NUMA aware resource alignment among this -// and other resource controllers. -func (p *none) GetPodTopologyHints(s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint { - return nil -} - -// GetAllocatableMemory returns the amount of allocatable memory for each NUMA node -func (p *none) GetAllocatableMemory(s state.State) []state.Block { - return []state.Block{} -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go deleted file mode 100644 index eabbab236..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/policy_static.go +++ /dev/null @@ -1,1066 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package memorymanager - -import ( - "fmt" - "sort" - - cadvisorapi "github.com/google/cadvisor/info/v1" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - corehelper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" - "k8s.io/kubernetes/pkg/kubelet/metrics" -) - -const policyTypeStatic policyType = "Static" - -type systemReservedMemory map[int]map[v1.ResourceName]uint64 -type reusableMemory map[string]map[string]map[v1.ResourceName]uint64 - -// staticPolicy is implementation of the policy interface for the static policy -type staticPolicy struct { - // machineInfo contains machine memory related information - machineInfo *cadvisorapi.MachineInfo - // reserved contains memory that reserved for kube - systemReserved systemReservedMemory - // topology manager reference to get container Topology affinity - affinity topologymanager.Store - // initContainersReusableMemory contains the memory allocated for init - // containers that can be reused. - // Note that the restartable init container memory is not included here, - // because it is not reusable. - initContainersReusableMemory reusableMemory -} - -var _ Policy = &staticPolicy{} - -// NewPolicyStatic returns new static policy instance -func NewPolicyStatic(machineInfo *cadvisorapi.MachineInfo, reserved systemReservedMemory, affinity topologymanager.Store) (Policy, error) { - var totalSystemReserved uint64 - for _, node := range reserved { - if _, ok := node[v1.ResourceMemory]; !ok { - continue - } - totalSystemReserved += node[v1.ResourceMemory] - } - - // check if we have some reserved memory for the system - if totalSystemReserved <= 0 { - return nil, fmt.Errorf("[memorymanager] you should specify the system reserved memory") - } - - return &staticPolicy{ - machineInfo: machineInfo, - systemReserved: reserved, - affinity: affinity, - initContainersReusableMemory: reusableMemory{}, - }, nil -} - -func (p *staticPolicy) Name() string { - return string(policyTypeStatic) -} - -func (p *staticPolicy) Start(s state.State) error { - if err := p.validateState(s); err != nil { - klog.ErrorS(err, "Invalid state, please drain node and remove policy state file") - return err - } - return nil -} - -// Allocate call is idempotent -func (p *staticPolicy) Allocate(s state.State, pod *v1.Pod, container *v1.Container) (rerr error) { - // allocate the memory only for guaranteed pods - qos := v1qos.GetPodQOS(pod) - if qos != v1.PodQOSGuaranteed { - klog.V(5).InfoS("Exclusive memory allocation skipped, pod QoS is not guaranteed", "pod", klog.KObj(pod), "containerName", container.Name, "qos", qos) - return nil - } - - podUID := string(pod.UID) - klog.InfoS("Allocate", "pod", klog.KObj(pod), "containerName", container.Name) - // container belongs in an exclusively allocated pool - metrics.MemoryManagerPinningRequestTotal.Inc() - defer func() { - if rerr != nil { - metrics.MemoryManagerPinningErrorsTotal.Inc() - } - }() - if blocks := s.GetMemoryBlocks(podUID, container.Name); blocks != nil { - p.updatePodReusableMemory(pod, container, blocks) - - klog.InfoS("Container already present in state, skipping", "pod", klog.KObj(pod), "containerName", container.Name) - return nil - } - - // Call Topology Manager to get the aligned affinity across all hint providers. - hint := p.affinity.GetAffinity(podUID, container.Name) - klog.InfoS("Got topology affinity", "pod", klog.KObj(pod), "podUID", pod.UID, "containerName", container.Name, "hint", hint) - - requestedResources, err := getRequestedResources(pod, container) - if err != nil { - return err - } - - machineState := s.GetMachineState() - bestHint := &hint - // topology manager returned the hint with NUMA affinity nil - // we should use the default NUMA affinity calculated the same way as for the topology manager - if hint.NUMANodeAffinity == nil { - defaultHint, err := p.getDefaultHint(machineState, pod, requestedResources) - if err != nil { - return err - } - - if !defaultHint.Preferred && bestHint.Preferred { - return fmt.Errorf("[memorymanager] failed to find the default preferred hint") - } - bestHint = defaultHint - } - - // topology manager returns the hint that does not satisfy completely the container request - // we should extend this hint to the one who will satisfy the request and include the current hint - if !isAffinitySatisfyRequest(machineState, bestHint.NUMANodeAffinity, requestedResources) { - extendedHint, err := p.extendTopologyManagerHint(machineState, pod, requestedResources, bestHint.NUMANodeAffinity) - if err != nil { - return err - } - - if !extendedHint.Preferred && bestHint.Preferred { - return fmt.Errorf("[memorymanager] failed to find the extended preferred hint") - } - bestHint = extendedHint - } - - // the best hint might violate the NUMA allocation rule on which - // NUMA node cannot have both single and cross NUMA node allocations - // https://kubernetes.io/blog/2021/08/11/kubernetes-1-22-feature-memory-manager-moves-to-beta/#single-vs-cross-numa-node-allocation - if isAffinityViolatingNUMAAllocations(machineState, bestHint.NUMANodeAffinity) { - return fmt.Errorf("[memorymanager] preferred hint violates NUMA node allocation") - } - - var containerBlocks []state.Block - maskBits := bestHint.NUMANodeAffinity.GetBits() - for resourceName, requestedSize := range requestedResources { - // update memory blocks - containerBlocks = append(containerBlocks, state.Block{ - NUMAAffinity: maskBits, - Size: requestedSize, - Type: resourceName, - }) - - podReusableMemory := p.getPodReusableMemory(pod, bestHint.NUMANodeAffinity, resourceName) - if podReusableMemory >= requestedSize { - requestedSize = 0 - } else { - requestedSize -= podReusableMemory - } - - // Update nodes memory state - p.updateMachineState(machineState, maskBits, resourceName, requestedSize) - } - - p.updatePodReusableMemory(pod, container, containerBlocks) - - s.SetMachineState(machineState) - s.SetMemoryBlocks(podUID, container.Name, containerBlocks) - - // update init containers memory blocks to reflect the fact that we re-used init containers memory - // it is possible that the size of the init container memory block will have 0 value, when all memory - // allocated for it was re-used - // we only do this so that the sum(memory_for_all_containers) == total amount of allocated memory to the pod, even - // though the final state here doesn't accurately reflect what was (in reality) allocated to each container - // TODO: we should refactor our state structs to reflect the amount of the re-used memory - p.updateInitContainersMemoryBlocks(s, pod, container, containerBlocks) - - klog.V(4).InfoS("Allocated exclusive memory", "pod", klog.KObj(pod), "containerName", container.Name) - return nil -} - -func (p *staticPolicy) updateMachineState(machineState state.NUMANodeMap, numaAffinity []int, resourceName v1.ResourceName, requestedSize uint64) { - for _, nodeID := range numaAffinity { - machineState[nodeID].NumberOfAssignments++ - machineState[nodeID].Cells = numaAffinity - - // we need to continue to update all affinity mask nodes - if requestedSize == 0 { - continue - } - - // update the node memory state - nodeResourceMemoryState := machineState[nodeID].MemoryMap[resourceName] - if nodeResourceMemoryState.Free <= 0 { - continue - } - - // the node has enough memory to satisfy the request - if nodeResourceMemoryState.Free >= requestedSize { - nodeResourceMemoryState.Reserved += requestedSize - nodeResourceMemoryState.Free -= requestedSize - requestedSize = 0 - continue - } - - // the node does not have enough memory, use the node remaining memory and move to the next node - requestedSize -= nodeResourceMemoryState.Free - nodeResourceMemoryState.Reserved += nodeResourceMemoryState.Free - nodeResourceMemoryState.Free = 0 - } -} - -func (p *staticPolicy) getPodReusableMemory(pod *v1.Pod, numaAffinity bitmask.BitMask, resourceName v1.ResourceName) uint64 { - podReusableMemory, ok := p.initContainersReusableMemory[string(pod.UID)] - if !ok { - return 0 - } - - numaReusableMemory, ok := podReusableMemory[numaAffinity.String()] - if !ok { - return 0 - } - - return numaReusableMemory[resourceName] -} - -// RemoveContainer call is idempotent -func (p *staticPolicy) RemoveContainer(s state.State, podUID string, containerName string) { - blocks := s.GetMemoryBlocks(podUID, containerName) - if blocks == nil { - return - } - - klog.InfoS("RemoveContainer", "podUID", podUID, "containerName", containerName) - s.Delete(podUID, containerName) - - // Mutate machine memory state to update free and reserved memory - machineState := s.GetMachineState() - for _, b := range blocks { - releasedSize := b.Size - for _, nodeID := range b.NUMAAffinity { - machineState[nodeID].NumberOfAssignments-- - - // once we do not have any memory allocations on this node, clear node groups - if machineState[nodeID].NumberOfAssignments == 0 { - machineState[nodeID].Cells = []int{nodeID} - } - - // we still need to pass over all NUMA node under the affinity mask to update them - if releasedSize == 0 { - continue - } - - nodeResourceMemoryState := machineState[nodeID].MemoryMap[b.Type] - - // if the node does not have reserved memory to free, continue to the next node - if nodeResourceMemoryState.Reserved == 0 { - continue - } - - // the reserved memory smaller than the amount of the memory that should be released - // release as much as possible and move to the next node - if nodeResourceMemoryState.Reserved < releasedSize { - releasedSize -= nodeResourceMemoryState.Reserved - nodeResourceMemoryState.Free += nodeResourceMemoryState.Reserved - nodeResourceMemoryState.Reserved = 0 - continue - } - - // the reserved memory big enough to satisfy the released memory - nodeResourceMemoryState.Free += releasedSize - nodeResourceMemoryState.Reserved -= releasedSize - releasedSize = 0 - } - } - - s.SetMachineState(machineState) -} - -func regenerateHints(pod *v1.Pod, ctn *v1.Container, ctnBlocks []state.Block, reqRsrc map[v1.ResourceName]uint64) map[string][]topologymanager.TopologyHint { - hints := map[string][]topologymanager.TopologyHint{} - for resourceName := range reqRsrc { - hints[string(resourceName)] = []topologymanager.TopologyHint{} - } - - if len(ctnBlocks) != len(reqRsrc) { - klog.InfoS("The number of requested resources by the container differs from the number of memory blocks", "pod", klog.KObj(pod), "containerName", ctn.Name) - return nil - } - - for _, b := range ctnBlocks { - if _, ok := reqRsrc[b.Type]; !ok { - klog.InfoS("Container requested resources but none available of this type", "pod", klog.KObj(pod), "containerName", ctn.Name, "type", b.Type) - return nil - } - - if b.Size != reqRsrc[b.Type] { - klog.InfoS("Memory already allocated with different numbers than requested", "pod", klog.KObj(pod), "containerName", ctn.Name, "type", b.Type, "requestedResource", reqRsrc[b.Type], "allocatedSize", b.Size) - return nil - } - - containerNUMAAffinity, err := bitmask.NewBitMask(b.NUMAAffinity...) - if err != nil { - klog.ErrorS(err, "Failed to generate NUMA bitmask", "pod", klog.KObj(pod), "containerName", ctn.Name, "type", b.Type) - return nil - } - - klog.InfoS("Regenerating TopologyHints, resource was already allocated to pod", "resourceName", b.Type, "pod", klog.KObj(pod), "podUID", pod.UID, "containerName", ctn.Name) - hints[string(b.Type)] = append(hints[string(b.Type)], topologymanager.TopologyHint{ - NUMANodeAffinity: containerNUMAAffinity, - Preferred: true, - }) - } - return hints -} - -func getPodRequestedResources(pod *v1.Pod) (map[v1.ResourceName]uint64, error) { - // Maximun resources requested by init containers at any given time. - reqRsrcsByInitCtrs := make(map[v1.ResourceName]uint64) - // Total resources requested by restartable init containers. - reqRsrcsByRestartableInitCtrs := make(map[v1.ResourceName]uint64) - for _, ctr := range pod.Spec.InitContainers { - reqRsrcs, err := getRequestedResources(pod, &ctr) - - if err != nil { - return nil, err - } - for rsrcName, qty := range reqRsrcs { - if _, ok := reqRsrcsByInitCtrs[rsrcName]; !ok { - reqRsrcsByInitCtrs[rsrcName] = uint64(0) - } - - // See https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/753-sidecar-containers#resources-calculation-for-scheduling-and-pod-admission - // for the detail. - if podutil.IsRestartableInitContainer(&ctr) { - reqRsrcsByRestartableInitCtrs[rsrcName] += qty - } else if reqRsrcsByRestartableInitCtrs[rsrcName]+qty > reqRsrcsByInitCtrs[rsrcName] { - reqRsrcsByInitCtrs[rsrcName] = reqRsrcsByRestartableInitCtrs[rsrcName] + qty - } - } - } - - reqRsrcsByAppCtrs := make(map[v1.ResourceName]uint64) - for _, ctr := range pod.Spec.Containers { - reqRsrcs, err := getRequestedResources(pod, &ctr) - - if err != nil { - return nil, err - } - for rsrcName, qty := range reqRsrcs { - if _, ok := reqRsrcsByAppCtrs[rsrcName]; !ok { - reqRsrcsByAppCtrs[rsrcName] = uint64(0) - } - - reqRsrcsByAppCtrs[rsrcName] += qty - } - } - - reqRsrcs := make(map[v1.ResourceName]uint64) - for rsrcName := range reqRsrcsByAppCtrs { - // Total resources requested by long-running containers. - reqRsrcsByLongRunningCtrs := reqRsrcsByAppCtrs[rsrcName] + reqRsrcsByRestartableInitCtrs[rsrcName] - reqRsrcs[rsrcName] = reqRsrcsByLongRunningCtrs - - if reqRsrcs[rsrcName] < reqRsrcsByInitCtrs[rsrcName] { - reqRsrcs[rsrcName] = reqRsrcsByInitCtrs[rsrcName] - } - } - return reqRsrcs, nil -} - -func (p *staticPolicy) GetPodTopologyHints(s state.State, pod *v1.Pod) map[string][]topologymanager.TopologyHint { - if v1qos.GetPodQOS(pod) != v1.PodQOSGuaranteed { - return nil - } - - reqRsrcs, err := getPodRequestedResources(pod) - if err != nil { - klog.ErrorS(err, "Failed to get pod requested resources", "pod", klog.KObj(pod), "podUID", pod.UID) - return nil - } - - for _, ctn := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { - containerBlocks := s.GetMemoryBlocks(string(pod.UID), ctn.Name) - // Short circuit to regenerate the same hints if there are already - // memory allocated for the container. This might happen after a - // kubelet restart, for example. - if containerBlocks != nil { - return regenerateHints(pod, &ctn, containerBlocks, reqRsrcs) - } - } - - // the pod topology hints calculated only once for all containers, so no need to pass re-usable state - return p.calculateHints(s.GetMachineState(), pod, reqRsrcs) -} - -// GetTopologyHints implements the topologymanager.HintProvider Interface -// and is consulted to achieve NUMA aware resource alignment among this -// and other resource controllers. -func (p *staticPolicy) GetTopologyHints(s state.State, pod *v1.Pod, container *v1.Container) map[string][]topologymanager.TopologyHint { - if v1qos.GetPodQOS(pod) != v1.PodQOSGuaranteed { - return nil - } - - requestedResources, err := getRequestedResources(pod, container) - if err != nil { - klog.ErrorS(err, "Failed to get container requested resources", "pod", klog.KObj(pod), "podUID", pod.UID, "containerName", container.Name) - return nil - } - - containerBlocks := s.GetMemoryBlocks(string(pod.UID), container.Name) - // Short circuit to regenerate the same hints if there are already - // memory allocated for the container. This might happen after a - // kubelet restart, for example. - if containerBlocks != nil { - return regenerateHints(pod, container, containerBlocks, requestedResources) - } - - return p.calculateHints(s.GetMachineState(), pod, requestedResources) -} - -func getRequestedResources(pod *v1.Pod, container *v1.Container) (map[v1.ResourceName]uint64, error) { - requestedResources := map[v1.ResourceName]uint64{} - resources := container.Resources.Requests - // In-place pod resize feature makes Container.Resources field mutable for CPU & memory. - // AllocatedResources holds the value of Container.Resources.Requests when the pod was admitted. - // We should return this value because this is what kubelet agreed to allocate for the container - // and the value configured with runtime. - if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { - containerStatuses := pod.Status.ContainerStatuses - if podutil.IsRestartableInitContainer(container) { - if len(pod.Status.InitContainerStatuses) != 0 { - containerStatuses = append(containerStatuses, pod.Status.InitContainerStatuses...) - } - } - if cs, ok := podutil.GetContainerStatus(containerStatuses, container.Name); ok { - resources = cs.AllocatedResources - } - } - for resourceName, quantity := range resources { - if resourceName != v1.ResourceMemory && !corehelper.IsHugePageResourceName(resourceName) { - continue - } - requestedSize, succeed := quantity.AsInt64() - if !succeed { - return nil, fmt.Errorf("[memorymanager] failed to represent quantity as int64") - } - requestedResources[resourceName] = uint64(requestedSize) - } - return requestedResources, nil -} - -func (p *staticPolicy) calculateHints(machineState state.NUMANodeMap, pod *v1.Pod, requestedResources map[v1.ResourceName]uint64) map[string][]topologymanager.TopologyHint { - var numaNodes []int - for n := range machineState { - numaNodes = append(numaNodes, n) - } - sort.Ints(numaNodes) - - // Initialize minAffinitySize to include all NUMA Cells. - minAffinitySize := len(numaNodes) - - hints := map[string][]topologymanager.TopologyHint{} - bitmask.IterateBitMasks(numaNodes, func(mask bitmask.BitMask) { - maskBits := mask.GetBits() - singleNUMAHint := len(maskBits) == 1 - - totalFreeSize := map[v1.ResourceName]uint64{} - totalAllocatableSize := map[v1.ResourceName]uint64{} - // calculate total free and allocatable memory for the node mask - for _, nodeID := range maskBits { - for resourceName := range requestedResources { - if _, ok := totalFreeSize[resourceName]; !ok { - totalFreeSize[resourceName] = 0 - } - totalFreeSize[resourceName] += machineState[nodeID].MemoryMap[resourceName].Free - - if _, ok := totalAllocatableSize[resourceName]; !ok { - totalAllocatableSize[resourceName] = 0 - } - totalAllocatableSize[resourceName] += machineState[nodeID].MemoryMap[resourceName].Allocatable - } - } - - // verify that for all memory types the node mask has enough allocatable resources - for resourceName, requestedSize := range requestedResources { - if totalAllocatableSize[resourceName] < requestedSize { - return - } - } - - // set the minimum amount of NUMA nodes that can satisfy the container resources requests - if mask.Count() < minAffinitySize { - minAffinitySize = mask.Count() - } - - // the node already in group with another node, it can not be used for the single NUMA node allocation - if singleNUMAHint && len(machineState[maskBits[0]].Cells) > 1 { - return - } - - for _, nodeID := range maskBits { - // the node already used for the memory allocation - if !singleNUMAHint && machineState[nodeID].NumberOfAssignments > 0 { - // the node used for the single NUMA memory allocation, it can not be used for the multi NUMA node allocation - if len(machineState[nodeID].Cells) == 1 { - return - } - - // the node already used with different group of nodes, it can not be use with in the current hint - if !areGroupsEqual(machineState[nodeID].Cells, maskBits) { - return - } - } - } - - // verify that for all memory types the node mask has enough free resources - for resourceName, requestedSize := range requestedResources { - podReusableMemory := p.getPodReusableMemory(pod, mask, resourceName) - if totalFreeSize[resourceName]+podReusableMemory < requestedSize { - return - } - } - - // add the node mask as topology hint for all memory types - for resourceName := range requestedResources { - if _, ok := hints[string(resourceName)]; !ok { - hints[string(resourceName)] = []topologymanager.TopologyHint{} - } - hints[string(resourceName)] = append(hints[string(resourceName)], topologymanager.TopologyHint{ - NUMANodeAffinity: mask, - Preferred: false, - }) - } - }) - - // update hints preferred according to multiNUMAGroups, in case when it wasn't provided, the default - // behaviour to prefer the minimal amount of NUMA nodes will be used - for resourceName := range requestedResources { - for i, hint := range hints[string(resourceName)] { - hints[string(resourceName)][i].Preferred = p.isHintPreferred(hint.NUMANodeAffinity.GetBits(), minAffinitySize) - } - } - - return hints -} - -func (p *staticPolicy) isHintPreferred(maskBits []int, minAffinitySize int) bool { - return len(maskBits) == minAffinitySize -} - -func areGroupsEqual(group1, group2 []int) bool { - sort.Ints(group1) - sort.Ints(group2) - - if len(group1) != len(group2) { - return false - } - - for i, elm := range group1 { - if group2[i] != elm { - return false - } - } - return true -} - -func (p *staticPolicy) validateState(s state.State) error { - machineState := s.GetMachineState() - memoryAssignments := s.GetMemoryAssignments() - - if len(machineState) == 0 { - // Machine state cannot be empty when assignments exist - if len(memoryAssignments) != 0 { - return fmt.Errorf("[memorymanager] machine state can not be empty when it has memory assignments") - } - - defaultMachineState := p.getDefaultMachineState() - s.SetMachineState(defaultMachineState) - - return nil - } - - // calculate all memory assigned to containers - expectedMachineState := p.getDefaultMachineState() - for pod, container := range memoryAssignments { - for containerName, blocks := range container { - for _, b := range blocks { - requestedSize := b.Size - for _, nodeID := range b.NUMAAffinity { - nodeState, ok := expectedMachineState[nodeID] - if !ok { - return fmt.Errorf("[memorymanager] (pod: %s, container: %s) the memory assignment uses the NUMA that does not exist", pod, containerName) - } - - nodeState.NumberOfAssignments++ - nodeState.Cells = b.NUMAAffinity - - memoryState, ok := nodeState.MemoryMap[b.Type] - if !ok { - return fmt.Errorf("[memorymanager] (pod: %s, container: %s) the memory assignment uses memory resource that does not exist", pod, containerName) - } - - if requestedSize == 0 { - continue - } - - // this node does not have enough memory continue to the next one - if memoryState.Free <= 0 { - continue - } - - // the node has enough memory to satisfy the request - if memoryState.Free >= requestedSize { - memoryState.Reserved += requestedSize - memoryState.Free -= requestedSize - requestedSize = 0 - continue - } - - // the node does not have enough memory, use the node remaining memory and move to the next node - requestedSize -= memoryState.Free - memoryState.Reserved += memoryState.Free - memoryState.Free = 0 - } - } - } - } - - // State has already been initialized from file (is not empty) - // Validate that total size, system reserved and reserved memory not changed, it can happen, when: - // - adding or removing physical memory bank from the node - // - change of kubelet system-reserved, kube-reserved or pre-reserved-memory-zone parameters - if !areMachineStatesEqual(machineState, expectedMachineState) { - return fmt.Errorf("[memorymanager] the expected machine state is different from the real one") - } - - return nil -} - -func areMachineStatesEqual(ms1, ms2 state.NUMANodeMap) bool { - if len(ms1) != len(ms2) { - klog.InfoS("Node states were different", "lengthNode1", len(ms1), "lengthNode2", len(ms2)) - return false - } - - for nodeID, nodeState1 := range ms1 { - nodeState2, ok := ms2[nodeID] - if !ok { - klog.InfoS("Node state didn't have node ID", "nodeID", nodeID) - return false - } - - if nodeState1.NumberOfAssignments != nodeState2.NumberOfAssignments { - klog.InfoS("Node state had a different number of memory assignments.", "assignment1", nodeState1.NumberOfAssignments, "assignment2", nodeState2.NumberOfAssignments) - return false - } - - if !areGroupsEqual(nodeState1.Cells, nodeState2.Cells) { - klog.InfoS("Node states had different groups", "stateNode1", nodeState1.Cells, "stateNode2", nodeState2.Cells) - return false - } - - if len(nodeState1.MemoryMap) != len(nodeState2.MemoryMap) { - klog.InfoS("Node state had memory maps of different lengths", "lengthNode1", len(nodeState1.MemoryMap), "lengthNode2", len(nodeState2.MemoryMap)) - return false - } - - for resourceName, memoryState1 := range nodeState1.MemoryMap { - memoryState2, ok := nodeState2.MemoryMap[resourceName] - if !ok { - klog.InfoS("Memory state didn't have resource", "resource", resourceName) - return false - } - - if !areMemoryStatesEqual(memoryState1, memoryState2, nodeID, resourceName) { - return false - } - - tmpState1 := state.MemoryTable{} - tmpState2 := state.MemoryTable{} - for _, nodeID := range nodeState1.Cells { - tmpState1.Free += ms1[nodeID].MemoryMap[resourceName].Free - tmpState1.Reserved += ms1[nodeID].MemoryMap[resourceName].Reserved - tmpState2.Free += ms2[nodeID].MemoryMap[resourceName].Free - tmpState2.Reserved += ms2[nodeID].MemoryMap[resourceName].Reserved - } - - if tmpState1.Free != tmpState2.Free { - klog.InfoS("NUMA node and resource had different memory states", "node", nodeID, "resource", resourceName, "field", "free", "free1", tmpState1.Free, "free2", tmpState2.Free, "memoryState1", *memoryState1, "memoryState2", *memoryState2) - return false - } - if tmpState1.Reserved != tmpState2.Reserved { - klog.InfoS("NUMA node and resource had different memory states", "node", nodeID, "resource", resourceName, "field", "reserved", "reserved1", tmpState1.Reserved, "reserved2", tmpState2.Reserved, "memoryState1", *memoryState1, "memoryState2", *memoryState2) - return false - } - } - } - return true -} - -func areMemoryStatesEqual(memoryState1, memoryState2 *state.MemoryTable, nodeID int, resourceName v1.ResourceName) bool { - if memoryState1.TotalMemSize != memoryState2.TotalMemSize { - klog.InfoS("Memory states for the NUMA node and resource are different", "node", nodeID, "resource", resourceName, "field", "TotalMemSize", "TotalMemSize1", memoryState1.TotalMemSize, "TotalMemSize2", memoryState2.TotalMemSize, "memoryState1", *memoryState1, "memoryState2", *memoryState2) - return false - } - - if memoryState1.SystemReserved != memoryState2.SystemReserved { - klog.InfoS("Memory states for the NUMA node and resource are different", "node", nodeID, "resource", resourceName, "field", "SystemReserved", "SystemReserved1", memoryState1.SystemReserved, "SystemReserved2", memoryState2.SystemReserved, "memoryState1", *memoryState1, "memoryState2", *memoryState2) - return false - } - - if memoryState1.Allocatable != memoryState2.Allocatable { - klog.InfoS("Memory states for the NUMA node and resource are different", "node", nodeID, "resource", resourceName, "field", "Allocatable", "Allocatable1", memoryState1.Allocatable, "Allocatable2", memoryState2.Allocatable, "memoryState1", *memoryState1, "memoryState2", *memoryState2) - return false - } - return true -} - -func (p *staticPolicy) getDefaultMachineState() state.NUMANodeMap { - defaultMachineState := state.NUMANodeMap{} - nodeHugepages := map[int]uint64{} - for _, node := range p.machineInfo.Topology { - defaultMachineState[node.Id] = &state.NUMANodeState{ - NumberOfAssignments: 0, - MemoryMap: map[v1.ResourceName]*state.MemoryTable{}, - Cells: []int{node.Id}, - } - - // fill memory table with huge pages values - for _, hugepage := range node.HugePages { - hugepageQuantity := resource.NewQuantity(int64(hugepage.PageSize)*1024, resource.BinarySI) - resourceName := corehelper.HugePageResourceName(*hugepageQuantity) - systemReserved := p.getResourceSystemReserved(node.Id, resourceName) - totalHugepagesSize := hugepage.NumPages * hugepage.PageSize * 1024 - allocatable := totalHugepagesSize - systemReserved - defaultMachineState[node.Id].MemoryMap[resourceName] = &state.MemoryTable{ - Allocatable: allocatable, - Free: allocatable, - Reserved: 0, - SystemReserved: systemReserved, - TotalMemSize: totalHugepagesSize, - } - if _, ok := nodeHugepages[node.Id]; !ok { - nodeHugepages[node.Id] = 0 - } - nodeHugepages[node.Id] += totalHugepagesSize - } - - // fill memory table with regular memory values - systemReserved := p.getResourceSystemReserved(node.Id, v1.ResourceMemory) - - allocatable := node.Memory - systemReserved - // remove memory allocated by hugepages - if allocatedByHugepages, ok := nodeHugepages[node.Id]; ok { - allocatable -= allocatedByHugepages - } - defaultMachineState[node.Id].MemoryMap[v1.ResourceMemory] = &state.MemoryTable{ - Allocatable: allocatable, - Free: allocatable, - Reserved: 0, - SystemReserved: systemReserved, - TotalMemSize: node.Memory, - } - } - return defaultMachineState -} - -func (p *staticPolicy) getResourceSystemReserved(nodeID int, resourceName v1.ResourceName) uint64 { - var systemReserved uint64 - if nodeSystemReserved, ok := p.systemReserved[nodeID]; ok { - if nodeMemorySystemReserved, ok := nodeSystemReserved[resourceName]; ok { - systemReserved = nodeMemorySystemReserved - } - } - return systemReserved -} - -func (p *staticPolicy) getDefaultHint(machineState state.NUMANodeMap, pod *v1.Pod, requestedResources map[v1.ResourceName]uint64) (*topologymanager.TopologyHint, error) { - hints := p.calculateHints(machineState, pod, requestedResources) - if len(hints) < 1 { - return nil, fmt.Errorf("[memorymanager] failed to get the default NUMA affinity, no NUMA nodes with enough memory is available") - } - - // hints for all memory types should be the same, so we will check hints only for regular memory type - return findBestHint(hints[string(v1.ResourceMemory)]), nil -} - -func isAffinitySatisfyRequest(machineState state.NUMANodeMap, mask bitmask.BitMask, requestedResources map[v1.ResourceName]uint64) bool { - totalFreeSize := map[v1.ResourceName]uint64{} - for _, nodeID := range mask.GetBits() { - for resourceName := range requestedResources { - if _, ok := totalFreeSize[resourceName]; !ok { - totalFreeSize[resourceName] = 0 - } - totalFreeSize[resourceName] += machineState[nodeID].MemoryMap[resourceName].Free - } - } - - // verify that for all memory types the node mask has enough resources - for resourceName, requestedSize := range requestedResources { - if totalFreeSize[resourceName] < requestedSize { - return false - } - } - - return true -} - -// extendTopologyManagerHint extends the topology manager hint, in case when it does not satisfy to the container request -// the topology manager uses bitwise AND to merge all topology hints into the best one, so in case of the restricted policy, -// it possible that we will get the subset of hint that we provided to the topology manager, in this case we want to extend -// it to the original one -func (p *staticPolicy) extendTopologyManagerHint(machineState state.NUMANodeMap, pod *v1.Pod, requestedResources map[v1.ResourceName]uint64, mask bitmask.BitMask) (*topologymanager.TopologyHint, error) { - hints := p.calculateHints(machineState, pod, requestedResources) - - var filteredHints []topologymanager.TopologyHint - // hints for all memory types should be the same, so we will check hints only for regular memory type - for _, hint := range hints[string(v1.ResourceMemory)] { - affinityBits := hint.NUMANodeAffinity.GetBits() - // filter all hints that does not include currentHint - if isHintInGroup(mask.GetBits(), affinityBits) { - filteredHints = append(filteredHints, hint) - } - } - - if len(filteredHints) < 1 { - return nil, fmt.Errorf("[memorymanager] failed to find NUMA nodes to extend the current topology hint") - } - - // try to find the preferred hint with the minimal number of NUMA nodes, relevant for the restricted policy - return findBestHint(filteredHints), nil -} - -func isHintInGroup(hint []int, group []int) bool { - sort.Ints(hint) - sort.Ints(group) - - hintIndex := 0 - for i := range group { - if hintIndex == len(hint) { - return true - } - - if group[i] != hint[hintIndex] { - continue - } - hintIndex++ - } - - return hintIndex == len(hint) -} - -func findBestHint(hints []topologymanager.TopologyHint) *topologymanager.TopologyHint { - // try to find the preferred hint with the minimal number of NUMA nodes, relevant for the restricted policy - bestHint := topologymanager.TopologyHint{} - for _, hint := range hints { - if bestHint.NUMANodeAffinity == nil { - bestHint = hint - continue - } - - // preferred of the current hint is true, when the extendedHint preferred is false - if hint.Preferred && !bestHint.Preferred { - bestHint = hint - continue - } - - // both hints has the same preferred value, but the current hint has less NUMA nodes than the extended one - if hint.Preferred == bestHint.Preferred && hint.NUMANodeAffinity.IsNarrowerThan(bestHint.NUMANodeAffinity) { - bestHint = hint - } - } - return &bestHint -} - -// GetAllocatableMemory returns the amount of allocatable memory for each NUMA node -func (p *staticPolicy) GetAllocatableMemory(s state.State) []state.Block { - var allocatableMemory []state.Block - machineState := s.GetMachineState() - for numaNodeID, numaNodeState := range machineState { - for resourceName, memoryTable := range numaNodeState.MemoryMap { - if memoryTable.Allocatable == 0 { - continue - } - - block := state.Block{ - NUMAAffinity: []int{numaNodeID}, - Type: resourceName, - Size: memoryTable.Allocatable, - } - allocatableMemory = append(allocatableMemory, block) - } - } - return allocatableMemory -} - -func (p *staticPolicy) updatePodReusableMemory(pod *v1.Pod, container *v1.Container, memoryBlocks []state.Block) { - podUID := string(pod.UID) - - // If pod entries to m.initContainersReusableMemory other than the current pod exist, delete them. - for uid := range p.initContainersReusableMemory { - if podUID != uid { - delete(p.initContainersReusableMemory, uid) - } - } - - if isRegularInitContainer(pod, container) { - if _, ok := p.initContainersReusableMemory[podUID]; !ok { - p.initContainersReusableMemory[podUID] = map[string]map[v1.ResourceName]uint64{} - } - - for _, block := range memoryBlocks { - blockBitMask, _ := bitmask.NewBitMask(block.NUMAAffinity...) - blockBitMaskString := blockBitMask.String() - - if _, ok := p.initContainersReusableMemory[podUID][blockBitMaskString]; !ok { - p.initContainersReusableMemory[podUID][blockBitMaskString] = map[v1.ResourceName]uint64{} - } - - if blockReusableMemory := p.initContainersReusableMemory[podUID][blockBitMaskString][block.Type]; block.Size > blockReusableMemory { - p.initContainersReusableMemory[podUID][blockBitMaskString][block.Type] = block.Size - } - } - - return - } - - // update re-usable memory once it used by the app container - for _, block := range memoryBlocks { - blockBitMask, _ := bitmask.NewBitMask(block.NUMAAffinity...) - if podReusableMemory := p.getPodReusableMemory(pod, blockBitMask, block.Type); podReusableMemory != 0 { - if block.Size >= podReusableMemory { - p.initContainersReusableMemory[podUID][blockBitMask.String()][block.Type] = 0 - } else { - p.initContainersReusableMemory[podUID][blockBitMask.String()][block.Type] -= block.Size - } - } - } -} - -func (p *staticPolicy) updateInitContainersMemoryBlocks(s state.State, pod *v1.Pod, container *v1.Container, containerMemoryBlocks []state.Block) { - podUID := string(pod.UID) - - for _, containerBlock := range containerMemoryBlocks { - blockSize := containerBlock.Size - for _, initContainer := range pod.Spec.InitContainers { - // we do not want to continue updates once we reach the current container - if initContainer.Name == container.Name { - break - } - - if blockSize == 0 { - break - } - - if podutil.IsRestartableInitContainer(&initContainer) { - // we should not reuse the resource from any restartable init - // container - continue - } - - initContainerBlocks := s.GetMemoryBlocks(podUID, initContainer.Name) - if len(initContainerBlocks) == 0 { - continue - } - - for i := range initContainerBlocks { - initContainerBlock := &initContainerBlocks[i] - if initContainerBlock.Size == 0 { - continue - } - - if initContainerBlock.Type != containerBlock.Type { - continue - } - - if !isNUMAAffinitiesEqual(initContainerBlock.NUMAAffinity, containerBlock.NUMAAffinity) { - continue - } - - if initContainerBlock.Size > blockSize { - initContainerBlock.Size -= blockSize - blockSize = 0 - } else { - blockSize -= initContainerBlock.Size - initContainerBlock.Size = 0 - } - } - - s.SetMemoryBlocks(podUID, initContainer.Name, initContainerBlocks) - } - } -} - -func isRegularInitContainer(pod *v1.Pod, container *v1.Container) bool { - for _, initContainer := range pod.Spec.InitContainers { - if initContainer.Name == container.Name { - return !podutil.IsRestartableInitContainer(&initContainer) - } - } - - return false -} - -func isNUMAAffinitiesEqual(numaAffinity1, numaAffinity2 []int) bool { - bitMask1, err := bitmask.NewBitMask(numaAffinity1...) - if err != nil { - klog.ErrorS(err, "failed to create bit mask", "numaAffinity1", numaAffinity1) - return false - } - - bitMask2, err := bitmask.NewBitMask(numaAffinity2...) - if err != nil { - klog.ErrorS(err, "failed to create bit mask", "numaAffinity2", numaAffinity2) - return false - } - - return bitMask1.IsEqual(bitMask2) -} - -func isAffinityViolatingNUMAAllocations(machineState state.NUMANodeMap, mask bitmask.BitMask) bool { - maskBits := mask.GetBits() - singleNUMAHint := len(maskBits) == 1 - for _, nodeID := range mask.GetBits() { - // the node was never used for the memory allocation - if machineState[nodeID].NumberOfAssignments == 0 { - continue - } - if singleNUMAHint { - continue - } - // the node used for the single NUMA memory allocation, it cannot be used for the multi NUMA node allocation - if len(machineState[nodeID].Cells) == 1 { - return true - } - // the node already used with a different group of nodes, it cannot be used within the current hint - if !areGroupsEqual(machineState[nodeID].Cells, maskBits) { - return true - } - } - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go deleted file mode 100644 index 93b1302ba..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/checkpoint.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "encoding/json" - - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum" -) - -var _ checkpointmanager.Checkpoint = &MemoryManagerCheckpoint{} - -// MemoryManagerCheckpoint struct is used to store memory/pod assignments in a checkpoint -type MemoryManagerCheckpoint struct { - PolicyName string `json:"policyName"` - MachineState NUMANodeMap `json:"machineState"` - Entries ContainerMemoryAssignments `json:"entries,omitempty"` - Checksum checksum.Checksum `json:"checksum"` -} - -// NewMemoryManagerCheckpoint returns an instance of Checkpoint -func NewMemoryManagerCheckpoint() *MemoryManagerCheckpoint { - //nolint:staticcheck // unexported-type-in-api user-facing error message - return &MemoryManagerCheckpoint{ - Entries: ContainerMemoryAssignments{}, - MachineState: NUMANodeMap{}, - } -} - -// MarshalCheckpoint returns marshalled checkpoint -func (mp *MemoryManagerCheckpoint) MarshalCheckpoint() ([]byte, error) { - // make sure checksum wasn't set before so it doesn't affect output checksum - mp.Checksum = 0 - mp.Checksum = checksum.New(mp) - return json.Marshal(*mp) -} - -// UnmarshalCheckpoint tries to unmarshal passed bytes to checkpoint -func (mp *MemoryManagerCheckpoint) UnmarshalCheckpoint(blob []byte) error { - return json.Unmarshal(blob, mp) -} - -// VerifyChecksum verifies that current checksum of checkpoint is valid -func (mp *MemoryManagerCheckpoint) VerifyChecksum() error { - ck := mp.Checksum - mp.Checksum = 0 - err := ck.Verify(mp) - mp.Checksum = ck - return err -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go deleted file mode 100644 index 322ca608e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - v1 "k8s.io/api/core/v1" -) - -// MemoryTable contains memory information -type MemoryTable struct { - TotalMemSize uint64 `json:"total"` - SystemReserved uint64 `json:"systemReserved"` - Allocatable uint64 `json:"allocatable"` - Reserved uint64 `json:"reserved"` - Free uint64 `json:"free"` -} - -// NUMANodeState contains NUMA node related information -type NUMANodeState struct { - // NumberOfAssignments contains a number memory assignments from this node - // When the container requires memory and hugepages it will increase number of assignments by two - NumberOfAssignments int `json:"numberOfAssignments"` - // MemoryTable contains NUMA node memory related information - MemoryMap map[v1.ResourceName]*MemoryTable `json:"memoryMap"` - // Cells contains the current NUMA node and all other nodes that are in a group with current NUMA node - // This parameter indicates if the current node is used for the multiple NUMA node memory allocation - // For example if some container has pinning 0,1,2, NUMA nodes 0,1,2 under the state will have - // this parameter equals to [0, 1, 2] - Cells []int `json:"cells"` -} - -// NUMANodeMap contains memory information for each NUMA node. -type NUMANodeMap map[int]*NUMANodeState - -// Clone returns a copy of NUMANodeMap -func (nm NUMANodeMap) Clone() NUMANodeMap { - clone := make(NUMANodeMap) - for node, s := range nm { - if s == nil { - clone[node] = nil - continue - } - - clone[node] = &NUMANodeState{} - clone[node].NumberOfAssignments = s.NumberOfAssignments - clone[node].Cells = append([]int{}, s.Cells...) - - if s.MemoryMap == nil { - continue - } - - clone[node].MemoryMap = map[v1.ResourceName]*MemoryTable{} - for memoryType, memoryTable := range s.MemoryMap { - clone[node].MemoryMap[memoryType] = &MemoryTable{ - Allocatable: memoryTable.Allocatable, - Free: memoryTable.Free, - Reserved: memoryTable.Reserved, - SystemReserved: memoryTable.SystemReserved, - TotalMemSize: memoryTable.TotalMemSize, - } - } - } - return clone -} - -// Block is a data structure used to represent a certain amount of memory -type Block struct { - // NUMAAffinity contains the string that represents NUMA affinity bitmask - NUMAAffinity []int `json:"numaAffinity"` - Type v1.ResourceName `json:"type"` - Size uint64 `json:"size"` -} - -// ContainerMemoryAssignments stores memory assignments of containers -type ContainerMemoryAssignments map[string]map[string][]Block - -// Clone returns a copy of ContainerMemoryAssignments -func (as ContainerMemoryAssignments) Clone() ContainerMemoryAssignments { - clone := make(ContainerMemoryAssignments) - for pod := range as { - clone[pod] = make(map[string][]Block) - for container, blocks := range as[pod] { - clone[pod][container] = append([]Block{}, blocks...) - } - } - return clone -} - -// Reader interface used to read current memory/pod assignment state -type Reader interface { - // GetMachineState returns Memory Map stored in the State - GetMachineState() NUMANodeMap - // GetMemoryBlocks returns memory assignments of a container - GetMemoryBlocks(podUID string, containerName string) []Block - // GetMemoryAssignments returns ContainerMemoryAssignments - GetMemoryAssignments() ContainerMemoryAssignments -} - -type writer interface { - // SetMachineState stores NUMANodeMap in State - SetMachineState(memoryMap NUMANodeMap) - // SetMemoryBlocks stores memory assignments of a container - SetMemoryBlocks(podUID string, containerName string, blocks []Block) - // SetMemoryAssignments sets ContainerMemoryAssignments by using the passed parameter - SetMemoryAssignments(assignments ContainerMemoryAssignments) - // Delete deletes corresponding Blocks from ContainerMemoryAssignments - Delete(podUID string, containerName string) - // ClearState clears machineState and ContainerMemoryAssignments - ClearState() -} - -// State interface provides methods for tracking and setting memory/pod assignment -type State interface { - Reader - writer -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go deleted file mode 100644 index dce0bda55..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_checkpoint.go +++ /dev/null @@ -1,184 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "fmt" - "path/filepath" - "sync" - - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager" - "k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors" -) - -var _ State = &stateCheckpoint{} - -type stateCheckpoint struct { - sync.RWMutex - cache State - policyName string - checkpointManager checkpointmanager.CheckpointManager - checkpointName string -} - -// NewCheckpointState creates new State for keeping track of memory/pod assignment with checkpoint backend -func NewCheckpointState(stateDir, checkpointName, policyName string) (State, error) { - checkpointManager, err := checkpointmanager.NewCheckpointManager(stateDir) - if err != nil { - return nil, fmt.Errorf("failed to initialize checkpoint manager: %v", err) - } - stateCheckpoint := &stateCheckpoint{ - cache: NewMemoryState(), - policyName: policyName, - checkpointManager: checkpointManager, - checkpointName: checkpointName, - } - - if err := stateCheckpoint.restoreState(); err != nil { - //nolint:staticcheck // ST1005 user-facing error message - return nil, fmt.Errorf("could not restore state from checkpoint: %v, please drain this node and delete the memory manager checkpoint file %q before restarting Kubelet", - err, filepath.Join(stateDir, checkpointName)) - } - - return stateCheckpoint, nil -} - -// restores state from a checkpoint and creates it if it doesn't exist -func (sc *stateCheckpoint) restoreState() error { - sc.Lock() - defer sc.Unlock() - var err error - - checkpoint := NewMemoryManagerCheckpoint() - if err = sc.checkpointManager.GetCheckpoint(sc.checkpointName, checkpoint); err != nil { - if err == errors.ErrCheckpointNotFound { - return sc.storeState() - } - return err - } - - if sc.policyName != checkpoint.PolicyName { - return fmt.Errorf("[memorymanager] configured policy %q differs from state checkpoint policy %q", sc.policyName, checkpoint.PolicyName) - } - - sc.cache.SetMachineState(checkpoint.MachineState) - sc.cache.SetMemoryAssignments(checkpoint.Entries) - - klog.V(2).InfoS("State checkpoint: restored state from checkpoint") - - return nil -} - -// saves state to a checkpoint, caller is responsible for locking -func (sc *stateCheckpoint) storeState() error { - checkpoint := NewMemoryManagerCheckpoint() - checkpoint.PolicyName = sc.policyName - checkpoint.MachineState = sc.cache.GetMachineState() - checkpoint.Entries = sc.cache.GetMemoryAssignments() - - err := sc.checkpointManager.CreateCheckpoint(sc.checkpointName, checkpoint) - if err != nil { - klog.ErrorS(err, "Could not save checkpoint") - return err - } - return nil -} - -// GetMemoryState returns Memory Map stored in the State -func (sc *stateCheckpoint) GetMachineState() NUMANodeMap { - sc.RLock() - defer sc.RUnlock() - - return sc.cache.GetMachineState() -} - -// GetMemoryBlocks returns memory assignments of a container -func (sc *stateCheckpoint) GetMemoryBlocks(podUID string, containerName string) []Block { - sc.RLock() - defer sc.RUnlock() - - return sc.cache.GetMemoryBlocks(podUID, containerName) -} - -// GetMemoryAssignments returns ContainerMemoryAssignments -func (sc *stateCheckpoint) GetMemoryAssignments() ContainerMemoryAssignments { - sc.RLock() - defer sc.RUnlock() - - return sc.cache.GetMemoryAssignments() -} - -// SetMachineState stores NUMANodeMap in State -func (sc *stateCheckpoint) SetMachineState(memoryMap NUMANodeMap) { - sc.Lock() - defer sc.Unlock() - - sc.cache.SetMachineState(memoryMap) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint") - } -} - -// SetMemoryBlocks stores memory assignments of container -func (sc *stateCheckpoint) SetMemoryBlocks(podUID string, containerName string, blocks []Block) { - sc.Lock() - defer sc.Unlock() - - sc.cache.SetMemoryBlocks(podUID, containerName, blocks) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint", "podUID", podUID, "containerName", containerName) - } -} - -// SetMemoryAssignments sets ContainerMemoryAssignments by using the passed parameter -func (sc *stateCheckpoint) SetMemoryAssignments(assignments ContainerMemoryAssignments) { - sc.Lock() - defer sc.Unlock() - - sc.cache.SetMemoryAssignments(assignments) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint") - } -} - -// Delete deletes corresponding Blocks from ContainerMemoryAssignments -func (sc *stateCheckpoint) Delete(podUID string, containerName string) { - sc.Lock() - defer sc.Unlock() - - sc.cache.Delete(podUID, containerName) - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint", "podUID", podUID, "containerName", containerName) - } -} - -// ClearState clears machineState and ContainerMemoryAssignments -func (sc *stateCheckpoint) ClearState() { - sc.Lock() - defer sc.Unlock() - - sc.cache.ClearState() - err := sc.storeState() - if err != nil { - klog.ErrorS(err, "Failed to store state to checkpoint") - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go deleted file mode 100644 index 19861c6e3..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state/state_mem.go +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package state - -import ( - "sync" - - "k8s.io/klog/v2" -) - -type stateMemory struct { - sync.RWMutex - assignments ContainerMemoryAssignments - machineState NUMANodeMap -} - -var _ State = &stateMemory{} - -// NewMemoryState creates new State for keeping track of cpu/pod assignment -func NewMemoryState() State { - klog.InfoS("Initializing new in-memory state store") - return &stateMemory{ - assignments: ContainerMemoryAssignments{}, - machineState: NUMANodeMap{}, - } -} - -// GetMemoryState returns Memory Map stored in the State -func (s *stateMemory) GetMachineState() NUMANodeMap { - s.RLock() - defer s.RUnlock() - - return s.machineState.Clone() -} - -// GetMemoryBlocks returns memory assignments of a container -func (s *stateMemory) GetMemoryBlocks(podUID string, containerName string) []Block { - s.RLock() - defer s.RUnlock() - - if res, ok := s.assignments[podUID][containerName]; ok { - return append([]Block{}, res...) - } - return nil -} - -// GetMemoryAssignments returns ContainerMemoryAssignments -func (s *stateMemory) GetMemoryAssignments() ContainerMemoryAssignments { - s.RLock() - defer s.RUnlock() - - return s.assignments.Clone() -} - -// SetMachineState stores NUMANodeMap in State -func (s *stateMemory) SetMachineState(nodeMap NUMANodeMap) { - s.Lock() - defer s.Unlock() - - s.machineState = nodeMap.Clone() - klog.InfoS("Updated machine memory state") -} - -// SetMemoryBlocks stores memory assignments of container -func (s *stateMemory) SetMemoryBlocks(podUID string, containerName string, blocks []Block) { - s.Lock() - defer s.Unlock() - - if _, ok := s.assignments[podUID]; !ok { - s.assignments[podUID] = map[string][]Block{} - } - - s.assignments[podUID][containerName] = append([]Block{}, blocks...) - klog.InfoS("Updated memory state", "podUID", podUID, "containerName", containerName) -} - -// SetMemoryAssignments sets ContainerMemoryAssignments by using the passed parameter -func (s *stateMemory) SetMemoryAssignments(assignments ContainerMemoryAssignments) { - s.Lock() - defer s.Unlock() - - s.assignments = assignments.Clone() - klog.V(5).InfoS("Updated Memory assignments", "assignments", assignments) -} - -// Delete deletes corresponding Blocks from ContainerMemoryAssignments -func (s *stateMemory) Delete(podUID string, containerName string) { - s.Lock() - defer s.Unlock() - - if _, ok := s.assignments[podUID]; !ok { - return - } - - delete(s.assignments[podUID], containerName) - if len(s.assignments[podUID]) == 0 { - delete(s.assignments, podUID) - } - klog.V(2).InfoS("Deleted memory assignment", "podUID", podUID, "containerName", containerName) -} - -// ClearState clears machineState and ContainerMemoryAssignments -func (s *stateMemory) ClearState() { - s.Lock() - defer s.Unlock() - - s.machineState = NUMANodeMap{} - s.assignments = make(ContainerMemoryAssignments) - klog.V(2).InfoS("Cleared state") -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go deleted file mode 100644 index 7fa180cef..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/node_container_manager_linux.go +++ /dev/null @@ -1,328 +0,0 @@ -//go:build linux -// +build linux - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "errors" - "fmt" - "strconv" - "strings" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - kubefeatures "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/events" - "k8s.io/kubernetes/pkg/kubelet/stats/pidlimit" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" -) - -const ( - defaultNodeAllocatableCgroupName = "kubepods" -) - -// createNodeAllocatableCgroups creates Node Allocatable Cgroup when CgroupsPerQOS flag is specified as true -func (cm *containerManagerImpl) createNodeAllocatableCgroups() error { - nodeAllocatable := cm.internalCapacity - // Use Node Allocatable limits instead of capacity if the user requested enforcing node allocatable. - nc := cm.NodeConfig.NodeAllocatableConfig - if cm.CgroupsPerQOS && nc.EnforceNodeAllocatable.Has(kubetypes.NodeAllocatableEnforcementKey) { - nodeAllocatable = cm.getNodeAllocatableInternalAbsolute() - } - - cgroupConfig := &CgroupConfig{ - Name: cm.cgroupRoot, - // The default limits for cpu shares can be very low which can lead to CPU starvation for pods. - ResourceParameters: cm.getCgroupConfig(nodeAllocatable, false), - } - if cm.cgroupManager.Exists(cgroupConfig.Name) { - return nil - } - if err := cm.cgroupManager.Create(cgroupConfig); err != nil { - klog.ErrorS(err, "Failed to create cgroup", "cgroupName", cm.cgroupRoot) - return err - } - return nil -} - -// enforceNodeAllocatableCgroups enforce Node Allocatable Cgroup settings. -func (cm *containerManagerImpl) enforceNodeAllocatableCgroups() error { - nc := cm.NodeConfig.NodeAllocatableConfig - - // We need to update limits on node allocatable cgroup no matter what because - // default cpu shares on cgroups are low and can cause cpu starvation. - nodeAllocatable := cm.internalCapacity - // Use Node Allocatable limits instead of capacity if the user requested enforcing node allocatable. - if cm.CgroupsPerQOS && nc.EnforceNodeAllocatable.Has(kubetypes.NodeAllocatableEnforcementKey) { - nodeAllocatable = cm.getNodeAllocatableInternalAbsolute() - } - - klog.V(4).InfoS("Attempting to enforce Node Allocatable", "config", nc) - - cgroupConfig := &CgroupConfig{ - Name: cm.cgroupRoot, - ResourceParameters: cm.getCgroupConfig(nodeAllocatable, false), - } - - // Using ObjectReference for events as the node maybe not cached; refer to #42701 for detail. - nodeRef := nodeRefFromNode(cm.nodeInfo.Name) - - // If Node Allocatable is enforced on a node that has not been drained or is updated on an existing node to a lower value, - // existing memory usage across pods might be higher than current Node Allocatable Memory Limits. - // Pod Evictions are expected to bring down memory usage to below Node Allocatable limits. - // Until evictions happen retry cgroup updates. - // Update limits on non root cgroup-root to be safe since the default limits for CPU can be too low. - // Check if cgroupRoot is set to a non-empty value (empty would be the root container) - if len(cm.cgroupRoot) > 0 { - go func() { - for { - err := cm.cgroupManager.Update(cgroupConfig) - if err == nil { - cm.recorder.Event(nodeRef, v1.EventTypeNormal, events.SuccessfulNodeAllocatableEnforcement, "Updated Node Allocatable limit across pods") - return - } - message := fmt.Sprintf("Failed to update Node Allocatable Limits %q: %v", cm.cgroupRoot, err) - cm.recorder.Event(nodeRef, v1.EventTypeWarning, events.FailedNodeAllocatableEnforcement, message) - time.Sleep(time.Minute) - } - }() - } - // Now apply kube reserved and system reserved limits if required. - if nc.EnforceNodeAllocatable.Has(kubetypes.SystemReservedEnforcementKey) { - klog.V(2).InfoS("Enforcing system reserved on cgroup", "cgroupName", nc.SystemReservedCgroupName, "limits", nc.SystemReserved) - if err := cm.enforceExistingCgroup(nc.SystemReservedCgroupName, nc.SystemReserved, false); err != nil { - message := fmt.Sprintf("Failed to enforce System Reserved Cgroup Limits on %q: %v", nc.SystemReservedCgroupName, err) - cm.recorder.Event(nodeRef, v1.EventTypeWarning, events.FailedNodeAllocatableEnforcement, message) - return errors.New(message) - } - cm.recorder.Eventf(nodeRef, v1.EventTypeNormal, events.SuccessfulNodeAllocatableEnforcement, "Updated limits on system reserved cgroup %v", nc.SystemReservedCgroupName) - } - if nc.EnforceNodeAllocatable.Has(kubetypes.KubeReservedEnforcementKey) { - klog.V(2).InfoS("Enforcing kube reserved on cgroup", "cgroupName", nc.KubeReservedCgroupName, "limits", nc.KubeReserved) - if err := cm.enforceExistingCgroup(nc.KubeReservedCgroupName, nc.KubeReserved, false); err != nil { - message := fmt.Sprintf("Failed to enforce Kube Reserved Cgroup Limits on %q: %v", nc.KubeReservedCgroupName, err) - cm.recorder.Event(nodeRef, v1.EventTypeWarning, events.FailedNodeAllocatableEnforcement, message) - return errors.New(message) - } - cm.recorder.Eventf(nodeRef, v1.EventTypeNormal, events.SuccessfulNodeAllocatableEnforcement, "Updated limits on kube reserved cgroup %v", nc.KubeReservedCgroupName) - } - - if nc.EnforceNodeAllocatable.Has(kubetypes.SystemReservedCompressibleEnforcementKey) { - klog.V(2).InfoS("Enforcing system reserved compressible on cgroup", "cgroupName", nc.SystemReservedCgroupName, "limits", nc.SystemReserved) - if err := cm.enforceExistingCgroup(nc.SystemReservedCgroupName, nc.SystemReserved, true); err != nil { - message := fmt.Sprintf("Failed to enforce System Reserved Compressible Cgroup Limits on %q: %v", nc.SystemReservedCgroupName, err) - cm.recorder.Event(nodeRef, v1.EventTypeWarning, events.FailedNodeAllocatableEnforcement, message) - return errors.New(message) - } - cm.recorder.Eventf(nodeRef, v1.EventTypeNormal, events.SuccessfulNodeAllocatableEnforcement, "Updated limits on system reserved cgroup %v", nc.SystemReservedCgroupName) - } - - if nc.EnforceNodeAllocatable.Has(kubetypes.KubeReservedCompressibleEnforcementKey) { - klog.V(2).InfoS("Enforcing kube reserved compressible on cgroup", "cgroupName", nc.KubeReservedCgroupName, "limits", nc.KubeReserved) - if err := cm.enforceExistingCgroup(nc.KubeReservedCgroupName, nc.KubeReserved, true); err != nil { - message := fmt.Sprintf("Failed to enforce Kube Reserved Compressible Cgroup Limits on %q: %v", nc.KubeReservedCgroupName, err) - cm.recorder.Event(nodeRef, v1.EventTypeWarning, events.FailedNodeAllocatableEnforcement, message) - return errors.New(message) - } - cm.recorder.Eventf(nodeRef, v1.EventTypeNormal, events.SuccessfulNodeAllocatableEnforcement, "Updated limits on kube reserved cgroup %v", nc.KubeReservedCgroupName) - } - return nil -} - -// enforceExistingCgroup updates the limits `rl` on existing cgroup `cName` using `cgroupManager` interface. -func (cm *containerManagerImpl) enforceExistingCgroup(cNameStr string, rl v1.ResourceList, compressibleResources bool) error { - cName := cm.cgroupManager.CgroupName(cNameStr) - rp := cm.getCgroupConfig(rl, compressibleResources) - if rp == nil { - return fmt.Errorf("%q cgroup is not configured properly", cName) - } - - // Enforce MemoryQoS for cgroups of kube-reserved/system-reserved. For more information, - // see https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2570-memory-qos - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.MemoryQoS) { - if rp.Memory != nil { - if rp.Unified == nil { - rp.Unified = make(map[string]string) - } - rp.Unified[Cgroup2MemoryMin] = strconv.FormatInt(*rp.Memory, 10) - } - } - - cgroupConfig := &CgroupConfig{ - Name: cName, - ResourceParameters: rp, - } - klog.V(4).InfoS("Enforcing limits on cgroup", "cgroupName", cName, "cpuShares", cgroupConfig.ResourceParameters.CPUShares, "memory", cgroupConfig.ResourceParameters.Memory, "pidsLimit", cgroupConfig.ResourceParameters.PidsLimit) - if err := cm.cgroupManager.Validate(cgroupConfig.Name); err != nil { - return err - } - if err := cm.cgroupManager.Update(cgroupConfig); err != nil { - return err - } - return nil -} - -// getCgroupConfig returns a ResourceConfig object that can be used to create or update cgroups via CgroupManager interface. -func (cm *containerManagerImpl) getCgroupConfig(rl v1.ResourceList, compressibleResourcesOnly bool) *ResourceConfig { - rc := getCgroupConfigInternal(rl, compressibleResourcesOnly) - if rc == nil { - return nil - } - - // In the case of a None policy, cgroupv2 and systemd cgroup manager, we must make sure systemd is aware of the cpuset cgroup. - // By default, systemd will not create it, as we've not chosen to delegate it, and we haven't included it in the Apply() request. - // However, this causes a bug where kubelet restarts unnecessarily (cpuset cgroup is created in the cgroupfs, but systemd - // doesn't know about it and deletes it, and then kubelet doesn't continue because the cgroup isn't configured as expected). - // An alternative is to delegate the `cpuset` cgroup to the kubelet, but that would require some plumbing in libcontainer, - // and this is sufficient. - // Only do so on None policy, as Static policy will do its own updating of the cpuset. - // Please see the comment on policy none's GetAllocatableCPUs - if cm.cpuManager.GetAllocatableCPUs().IsEmpty() { - rc.CPUSet = cm.cpuManager.GetAllCPUs() - } - - return rc -} - -// getCgroupConfigInternal are the pieces of getCgroupConfig that don't require the cm object. -// This is added to unit test without needing to create a full containerManager -func getCgroupConfigInternal(rl v1.ResourceList, compressibleResourcesOnly bool) *ResourceConfig { - // TODO(vishh): Set CPU Quota if necessary. - if rl == nil { - return nil - } - var rc ResourceConfig - - setCompressibleResources := func() { - if q, exists := rl[v1.ResourceCPU]; exists { - // CPU is defined in milli-cores. - val := MilliCPUToShares(q.MilliValue()) - rc.CPUShares = &val - } - } - - // Only return compressible resources - if compressibleResourcesOnly { - setCompressibleResources() - } else { - if q, exists := rl[v1.ResourceMemory]; exists { - // Memory is defined in bytes. - val := q.Value() - rc.Memory = &val - } - - setCompressibleResources() - - if q, exists := rl[pidlimit.PIDs]; exists { - val := q.Value() - rc.PidsLimit = &val - } - rc.HugePageLimit = HugePageLimits(rl) - } - return &rc -} - -// GetNodeAllocatableAbsolute returns the absolute value of Node Allocatable which is primarily useful for enforcement. -// Note that not all resources that are available on the node are included in the returned list of resources. -// Returns a ResourceList. -func (cm *containerManagerImpl) GetNodeAllocatableAbsolute() v1.ResourceList { - return cm.getNodeAllocatableAbsoluteImpl(cm.capacity) -} - -func (cm *containerManagerImpl) getNodeAllocatableAbsoluteImpl(capacity v1.ResourceList) v1.ResourceList { - result := make(v1.ResourceList) - for k, v := range capacity { - value := v.DeepCopy() - if cm.NodeConfig.SystemReserved != nil { - value.Sub(cm.NodeConfig.SystemReserved[k]) - } - if cm.NodeConfig.KubeReserved != nil { - value.Sub(cm.NodeConfig.KubeReserved[k]) - } - if value.Sign() < 0 { - // Negative Allocatable resources don't make sense. - value.Set(0) - } - result[k] = value - } - return result -} - -// getNodeAllocatableInternalAbsolute is similar to getNodeAllocatableAbsolute except that -// it also includes internal resources (currently process IDs). It is intended for setting -// up top level cgroups only. -func (cm *containerManagerImpl) getNodeAllocatableInternalAbsolute() v1.ResourceList { - return cm.getNodeAllocatableAbsoluteImpl(cm.internalCapacity) -} - -// GetNodeAllocatableReservation returns amount of compute or storage resource that have to be reserved on this node from scheduling. -func (cm *containerManagerImpl) GetNodeAllocatableReservation() v1.ResourceList { - evictionReservation := hardEvictionReservation(cm.HardEvictionThresholds, cm.capacity) - result := make(v1.ResourceList) - for k := range cm.capacity { - value := resource.NewQuantity(0, resource.DecimalSI) - if cm.NodeConfig.SystemReserved != nil { - value.Add(cm.NodeConfig.SystemReserved[k]) - } - if cm.NodeConfig.KubeReserved != nil { - value.Add(cm.NodeConfig.KubeReserved[k]) - } - if evictionReservation != nil { - value.Add(evictionReservation[k]) - } - if !value.IsZero() { - result[k] = *value - } - } - return result -} - -// validateNodeAllocatable ensures that the user specified Node Allocatable Configuration doesn't reserve more than the node capacity. -// Returns error if the configuration is invalid, nil otherwise. -func (cm *containerManagerImpl) validateNodeAllocatable() error { - var errors []string - nar := cm.GetNodeAllocatableReservation() - for k, v := range nar { - value := cm.capacity[k].DeepCopy() - value.Sub(v) - - if value.Sign() < 0 { - errors = append(errors, fmt.Sprintf("Resource %q has a reservation of %v but capacity of %v. Expected capacity >= reservation.", k, v, cm.capacity[k])) - } - } - - if len(errors) > 0 { - return fmt.Errorf("invalid Node Allocatable configuration. %s", strings.Join(errors, " ")) - } - return nil -} - -// Using ObjectReference for events as the node maybe not cached; refer to #42701 for detail. -func nodeRefFromNode(nodeName string) *v1.ObjectReference { - return &v1.ObjectReference{ - Kind: "Node", - Name: nodeName, - UID: types.UID(nodeName), - Namespace: "", - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go deleted file mode 100644 index 3159e0ed7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_linux.go +++ /dev/null @@ -1,362 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "errors" - "fmt" - "os" - "path" - "strings" - - libcontainercgroups "github.com/opencontainers/cgroups" - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - utilerrors "k8s.io/apimachinery/pkg/util/errors" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" - kubefeatures "k8s.io/kubernetes/pkg/features" -) - -const ( - podCgroupNamePrefix = "pod" -) - -// podContainerManagerImpl implements podContainerManager interface. -// It is the general implementation which allows pod level container -// management if qos Cgroup is enabled. -type podContainerManagerImpl struct { - // qosContainersInfo hold absolute paths of the top level qos containers - qosContainersInfo QOSContainersInfo - // Stores the mounted cgroup subsystems - subsystems *CgroupSubsystems - // cgroupManager is the cgroup Manager Object responsible for managing all - // pod cgroups. - cgroupManager CgroupManager - // Maximum number of pids in a pod - podPidsLimit int64 - // enforceCPULimits controls whether cfs quota is enforced or not - enforceCPULimits bool - // cpuCFSQuotaPeriod is the cfs period value, cfs_period_us, setting per - // node for all containers in usec - cpuCFSQuotaPeriod uint64 - // podContainerManager is the ContainerManager running on the machine - podContainerManager ContainerManager -} - -// Make sure that podContainerManagerImpl implements the PodContainerManager interface -var _ PodContainerManager = &podContainerManagerImpl{} - -// Exists checks if the pod's cgroup already exists -func (m *podContainerManagerImpl) Exists(pod *v1.Pod) bool { - podContainerName, _ := m.GetPodContainerName(pod) - return m.cgroupManager.Exists(podContainerName) -} - -// EnsureExists takes a pod as argument and makes sure that -// pod cgroup exists if qos cgroup hierarchy flag is enabled. -// If the pod level container doesn't already exist it is created. -func (m *podContainerManagerImpl) EnsureExists(pod *v1.Pod) error { - // check if container already exist - alreadyExists := m.Exists(pod) - if !alreadyExists { - enforceCPULimits := m.enforceCPULimits - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.DisableCPUQuotaWithExclusiveCPUs) && m.podContainerManager.PodHasExclusiveCPUs(pod) { - klog.V(2).InfoS("Disabled CFS quota", "pod", klog.KObj(pod)) - enforceCPULimits = false - } - enforceMemoryQoS := false - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.MemoryQoS) && - libcontainercgroups.IsCgroup2UnifiedMode() { - enforceMemoryQoS = true - } - // Create the pod container - podContainerName, _ := m.GetPodContainerName(pod) - containerConfig := &CgroupConfig{ - Name: podContainerName, - ResourceParameters: ResourceConfigForPod(pod, enforceCPULimits, m.cpuCFSQuotaPeriod, enforceMemoryQoS), - } - if m.podPidsLimit > 0 { - containerConfig.ResourceParameters.PidsLimit = &m.podPidsLimit - } - if enforceMemoryQoS { - klog.V(4).InfoS("MemoryQoS config for pod", "pod", klog.KObj(pod), "unified", containerConfig.ResourceParameters.Unified) - } - if err := m.cgroupManager.Create(containerConfig); err != nil { - return fmt.Errorf("failed to create container for %v : %v", podContainerName, err) - } - } - return nil -} - -// GetPodContainerName returns the CgroupName identifier, and its literal cgroupfs form on the host. -func (m *podContainerManagerImpl) GetPodContainerName(pod *v1.Pod) (CgroupName, string) { - podQOS := v1qos.GetPodQOS(pod) - // Get the parent QOS container name - var parentContainer CgroupName - switch podQOS { - case v1.PodQOSGuaranteed: - parentContainer = m.qosContainersInfo.Guaranteed - case v1.PodQOSBurstable: - parentContainer = m.qosContainersInfo.Burstable - case v1.PodQOSBestEffort: - parentContainer = m.qosContainersInfo.BestEffort - } - podContainer := GetPodCgroupNameSuffix(pod.UID) - - // Get the absolute path of the cgroup - cgroupName := NewCgroupName(parentContainer, podContainer) - // Get the literal cgroupfs name - cgroupfsName := m.cgroupManager.Name(cgroupName) - - return cgroupName, cgroupfsName -} - -func (m *podContainerManagerImpl) GetPodCgroupMemoryUsage(pod *v1.Pod) (uint64, error) { - podCgroupName, _ := m.GetPodContainerName(pod) - memUsage, err := m.cgroupManager.MemoryUsage(podCgroupName) - if err != nil { - return 0, err - } - return uint64(memUsage), nil -} - -func (m *podContainerManagerImpl) GetPodCgroupConfig(pod *v1.Pod, resource v1.ResourceName) (*ResourceConfig, error) { - podCgroupName, _ := m.GetPodContainerName(pod) - return m.cgroupManager.GetCgroupConfig(podCgroupName, resource) -} - -func (m *podContainerManagerImpl) SetPodCgroupConfig(pod *v1.Pod, resourceConfig *ResourceConfig) error { - podCgroupName, _ := m.GetPodContainerName(pod) - return m.cgroupManager.SetCgroupConfig(podCgroupName, resourceConfig) -} - -// Kill one process ID -func (m *podContainerManagerImpl) killOnePid(pid int) error { - // os.FindProcess never returns an error on POSIX - // https://go-review.googlesource.com/c/go/+/19093 - p, _ := os.FindProcess(pid) - if err := p.Kill(); err != nil { - // If the process already exited, that's fine. - if errors.Is(err, os.ErrProcessDone) { - klog.V(3).InfoS("Process no longer exists", "pid", pid) - return nil - } - return err - } - return nil -} - -// Scan through the whole cgroup directory and kill all processes either -// attached to the pod cgroup or to a container cgroup under the pod cgroup -func (m *podContainerManagerImpl) tryKillingCgroupProcesses(podCgroup CgroupName) error { - pidsToKill := m.cgroupManager.Pids(podCgroup) - // No pids charged to the terminated pod cgroup return - if len(pidsToKill) == 0 { - return nil - } - - var errlist []error - // os.Kill often errors out, - // We try killing all the pids multiple times - removed := map[int]bool{} - for i := 0; i < 5; i++ { - if i != 0 { - klog.V(3).InfoS("Attempt failed to kill all unwanted process from cgroup, retrying", "attempt", i, "cgroupName", podCgroup) - } - errlist = []error{} - for _, pid := range pidsToKill { - if _, ok := removed[pid]; ok { - continue - } - klog.V(3).InfoS("Attempting to kill process from cgroup", "pid", pid, "cgroupName", podCgroup) - if err := m.killOnePid(pid); err != nil { - klog.V(3).InfoS("Failed to kill process from cgroup", "pid", pid, "cgroupName", podCgroup, "err", err) - errlist = append(errlist, err) - } else { - removed[pid] = true - } - } - if len(errlist) == 0 { - klog.V(3).InfoS("Successfully killed all unwanted processes from cgroup", "cgroupName", podCgroup) - return nil - } - } - return utilerrors.NewAggregate(errlist) -} - -// Destroy destroys the pod container cgroup paths -func (m *podContainerManagerImpl) Destroy(podCgroup CgroupName) error { - // Try killing all the processes attached to the pod cgroup - if err := m.tryKillingCgroupProcesses(podCgroup); err != nil { - klog.InfoS("Failed to kill all the processes attached to cgroup", "cgroupName", podCgroup, "err", err) - return fmt.Errorf("failed to kill all the processes attached to the %v cgroups : %v", podCgroup, err) - } - - // Now its safe to remove the pod's cgroup - containerConfig := &CgroupConfig{ - Name: podCgroup, - ResourceParameters: &ResourceConfig{}, - } - if err := m.cgroupManager.Destroy(containerConfig); err != nil { - klog.InfoS("Failed to delete cgroup paths", "cgroupName", podCgroup, "err", err) - return fmt.Errorf("failed to delete cgroup paths for %v : %v", podCgroup, err) - } - return nil -} - -// ReduceCPULimits reduces the CPU CFS values to the minimum amount of shares. -func (m *podContainerManagerImpl) ReduceCPULimits(podCgroup CgroupName) error { - return m.cgroupManager.ReduceCPULimits(podCgroup) -} - -// IsPodCgroup returns true if the literal cgroupfs name corresponds to a pod -func (m *podContainerManagerImpl) IsPodCgroup(cgroupfs string) (bool, types.UID) { - // convert the literal cgroupfs form to the driver specific value - cgroupName := m.cgroupManager.CgroupName(cgroupfs) - qosContainersList := [3]CgroupName{m.qosContainersInfo.BestEffort, m.qosContainersInfo.Burstable, m.qosContainersInfo.Guaranteed} - basePath := "" - for _, qosContainerName := range qosContainersList { - // a pod cgroup is a direct child of a qos node, so check if its a match - if len(cgroupName) == len(qosContainerName)+1 { - basePath = cgroupName[len(qosContainerName)] - } - } - if basePath == "" { - return false, types.UID("") - } - if !strings.HasPrefix(basePath, podCgroupNamePrefix) { - return false, types.UID("") - } - parts := strings.Split(basePath, podCgroupNamePrefix) - if len(parts) != 2 { - return false, types.UID("") - } - return true, types.UID(parts[1]) -} - -// GetAllPodsFromCgroups scans through all the subsystems of pod cgroups -// Get list of pods whose cgroup still exist on the cgroup mounts -func (m *podContainerManagerImpl) GetAllPodsFromCgroups() (map[types.UID]CgroupName, error) { - // Map for storing all the found pods on the disk - foundPods := make(map[types.UID]CgroupName) - qosContainersList := [3]CgroupName{m.qosContainersInfo.BestEffort, m.qosContainersInfo.Burstable, m.qosContainersInfo.Guaranteed} - // Scan through all the subsystem mounts - // and through each QoS cgroup directory for each subsystem mount - // If a pod cgroup exists in even a single subsystem mount - // we will attempt to delete it - for _, val := range m.subsystems.MountPoints { - for _, qosContainerName := range qosContainersList { - // get the subsystems QoS cgroup absolute name - qcConversion := m.cgroupManager.Name(qosContainerName) - qc := path.Join(val, qcConversion) - dirInfo, err := os.ReadDir(qc) - if err != nil { - if os.IsNotExist(err) { - continue - } - return nil, fmt.Errorf("failed to read the cgroup directory %v : %v", qc, err) - } - for i := range dirInfo { - // its not a directory, so continue on... - if !dirInfo[i].IsDir() { - continue - } - // convert the concrete cgroupfs name back to an internal identifier - // this is needed to handle path conversion for systemd environments. - // we pass the fully qualified path so decoding can work as expected - // since systemd encodes the path in each segment. - cgroupfsPath := path.Join(qcConversion, dirInfo[i].Name()) - internalPath := m.cgroupManager.CgroupName(cgroupfsPath) - // we only care about base segment of the converted path since that - // is what we are reading currently to know if it is a pod or not. - basePath := internalPath[len(internalPath)-1] - if !strings.Contains(basePath, podCgroupNamePrefix) { - continue - } - // we then split the name on the pod prefix to determine the uid - parts := strings.Split(basePath, podCgroupNamePrefix) - // the uid is missing, so we log the unexpected cgroup not of form pod - if len(parts) != 2 { - klog.InfoS("Pod cgroup manager ignored unexpected cgroup because it is not a pod", "path", cgroupfsPath) - continue - } - podUID := parts[1] - foundPods[types.UID(podUID)] = internalPath - } - } - } - return foundPods, nil -} - -// podContainerManagerNoop implements podContainerManager interface. -// It is a no-op implementation and basically does nothing -// podContainerManagerNoop is used in case the QoS cgroup Hierarchy is not -// enabled, so Exists() returns true always as the cgroupRoot -// is expected to always exist. -type podContainerManagerNoop struct { - cgroupRoot CgroupName -} - -// Make sure that podContainerManagerStub implements the PodContainerManager interface -var _ PodContainerManager = &podContainerManagerNoop{} - -func (m *podContainerManagerNoop) Exists(_ *v1.Pod) bool { - return true -} - -func (m *podContainerManagerNoop) EnsureExists(_ *v1.Pod) error { - return nil -} - -func (m *podContainerManagerNoop) GetPodContainerName(_ *v1.Pod) (CgroupName, string) { - return m.cgroupRoot, "" -} - -func (m *podContainerManagerNoop) GetPodContainerNameForDriver(_ *v1.Pod) string { - return "" -} - -// Destroy destroys the pod container cgroup paths -func (m *podContainerManagerNoop) Destroy(_ CgroupName) error { - return nil -} - -func (m *podContainerManagerNoop) ReduceCPULimits(_ CgroupName) error { - return nil -} - -func (m *podContainerManagerNoop) GetAllPodsFromCgroups() (map[types.UID]CgroupName, error) { - return nil, nil -} - -func (m *podContainerManagerNoop) IsPodCgroup(cgroupfs string) (bool, types.UID) { - return false, types.UID("") -} - -func (m *podContainerManagerNoop) GetPodCgroupMemoryUsage(_ *v1.Pod) (uint64, error) { - return 0, nil -} - -func (m *podContainerManagerNoop) GetPodCgroupConfig(_ *v1.Pod, _ v1.ResourceName) (*ResourceConfig, error) { - return nil, nil -} - -func (m *podContainerManagerNoop) SetPodCgroupConfig(_ *v1.Pod, _ *ResourceConfig) error { - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_stub.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_stub.go deleted file mode 100644 index 36a995c18..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/pod_container_manager_stub.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -type podContainerManagerStub struct { -} - -var _ PodContainerManager = &podContainerManagerStub{} - -func (m *podContainerManagerStub) Exists(_ *v1.Pod) bool { - return true -} - -func (m *podContainerManagerStub) EnsureExists(_ *v1.Pod) error { - return nil -} - -func (m *podContainerManagerStub) GetPodContainerName(_ *v1.Pod) (CgroupName, string) { - return nil, "" -} - -func (m *podContainerManagerStub) Destroy(_ CgroupName) error { - return nil -} - -func (m *podContainerManagerStub) ReduceCPULimits(_ CgroupName) error { - return nil -} - -func (m *podContainerManagerStub) GetAllPodsFromCgroups() (map[types.UID]CgroupName, error) { - return nil, nil -} - -func (m *podContainerManagerStub) IsPodCgroup(cgroupfs string) (bool, types.UID) { - return false, types.UID("") -} - -func (m *podContainerManagerStub) GetPodCgroupMemoryUsage(_ *v1.Pod) (uint64, error) { - return 0, nil -} - -func (m *podContainerManagerStub) GetPodCgroupMemoryLimit(_ *v1.Pod) (uint64, error) { - return 0, nil -} - -func (m *podContainerManagerStub) GetPodCgroupCpuLimit(_ *v1.Pod) (int64, uint64, uint64, error) { - return 0, 0, 0, nil -} - -func (m *podContainerManagerStub) SetPodCgroupMemoryLimit(_ *v1.Pod, _ int64) error { - return nil -} - -func (m *podContainerManagerStub) SetPodCgroupCpuLimit(_ *v1.Pod, _ *int64, _, _ *uint64) error { - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go deleted file mode 100644 index aac639c1e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/qos_container_manager_linux.go +++ /dev/null @@ -1,407 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - "fmt" - "strconv" - "strings" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/klog/v2" - - "k8s.io/apimachinery/pkg/util/wait" - - units "github.com/docker/go-units" - libcontainercgroups "github.com/opencontainers/cgroups" - utilfeature "k8s.io/apiserver/pkg/util/feature" - - "k8s.io/component-helpers/resource" - v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" - kubefeatures "k8s.io/kubernetes/pkg/features" -) - -const ( - // how often the qos cgroup manager will perform periodic update - // of the qos level cgroup resource constraints - periodicQOSCgroupUpdateInterval = 1 * time.Minute -) - -type QOSContainerManager interface { - Start(func() v1.ResourceList, ActivePodsFunc) error - GetQOSContainersInfo() QOSContainersInfo - UpdateCgroups() error -} - -type qosContainerManagerImpl struct { - sync.Mutex - qosContainersInfo QOSContainersInfo - subsystems *CgroupSubsystems - cgroupManager CgroupManager - activePods ActivePodsFunc - getNodeAllocatable func() v1.ResourceList - cgroupRoot CgroupName - qosReserved map[v1.ResourceName]int64 -} - -func NewQOSContainerManager(subsystems *CgroupSubsystems, cgroupRoot CgroupName, nodeConfig NodeConfig, cgroupManager CgroupManager) (QOSContainerManager, error) { - if !nodeConfig.CgroupsPerQOS { - return &qosContainerManagerNoop{ - cgroupRoot: cgroupRoot, - }, nil - } - - return &qosContainerManagerImpl{ - subsystems: subsystems, - cgroupManager: cgroupManager, - cgroupRoot: cgroupRoot, - qosReserved: nodeConfig.QOSReserved, - }, nil -} - -func (m *qosContainerManagerImpl) GetQOSContainersInfo() QOSContainersInfo { - return m.qosContainersInfo -} - -func (m *qosContainerManagerImpl) Start(getNodeAllocatable func() v1.ResourceList, activePods ActivePodsFunc) error { - cm := m.cgroupManager - rootContainer := m.cgroupRoot - - if err := cm.Validate(rootContainer); err != nil { - return fmt.Errorf("error validating root container %v : %w", rootContainer, err) - } - - // Top level for Qos containers are created only for Burstable - // and Best Effort classes - qosClasses := map[v1.PodQOSClass]CgroupName{ - v1.PodQOSBurstable: NewCgroupName(rootContainer, strings.ToLower(string(v1.PodQOSBurstable))), - v1.PodQOSBestEffort: NewCgroupName(rootContainer, strings.ToLower(string(v1.PodQOSBestEffort))), - } - - // Create containers for both qos classes - for qosClass, containerName := range qosClasses { - resourceParameters := &ResourceConfig{} - // the BestEffort QoS class has a statically configured minShares value - if qosClass == v1.PodQOSBestEffort { - minShares := uint64(MinShares) - resourceParameters.CPUShares = &minShares - } - - // containerConfig object stores the cgroup specifications - containerConfig := &CgroupConfig{ - Name: containerName, - ResourceParameters: resourceParameters, - } - - // for each enumerated huge page size, the qos tiers are unbounded - m.setHugePagesUnbounded(containerConfig) - - // check if it exists - if !cm.Exists(containerName) { - if err := cm.Create(containerConfig); err != nil { - return fmt.Errorf("failed to create top level %v QOS cgroup : %v", qosClass, err) - } - } else { - // to ensure we actually have the right state, we update the config on startup - if err := cm.Update(containerConfig); err != nil { - return fmt.Errorf("failed to update top level %v QOS cgroup : %v", qosClass, err) - } - } - } - // Store the top level qos container names - m.qosContainersInfo = QOSContainersInfo{ - Guaranteed: rootContainer, - Burstable: qosClasses[v1.PodQOSBurstable], - BestEffort: qosClasses[v1.PodQOSBestEffort], - } - m.getNodeAllocatable = getNodeAllocatable - m.activePods = activePods - - // update qos cgroup tiers on startup and in periodic intervals - // to ensure desired state is in sync with actual state. - go wait.Until(func() { - err := m.UpdateCgroups() - if err != nil { - klog.InfoS("Failed to reserve QoS requests", "err", err) - } - }, periodicQOSCgroupUpdateInterval, wait.NeverStop) - - return nil -} - -// setHugePagesUnbounded ensures hugetlb is effectively unbounded -func (m *qosContainerManagerImpl) setHugePagesUnbounded(cgroupConfig *CgroupConfig) error { - hugePageLimit := map[int64]int64{} - for _, pageSize := range libcontainercgroups.HugePageSizes() { - pageSizeBytes, err := units.RAMInBytes(pageSize) - if err != nil { - return err - } - hugePageLimit[pageSizeBytes] = int64(1 << 62) - } - cgroupConfig.ResourceParameters.HugePageLimit = hugePageLimit - return nil -} - -func (m *qosContainerManagerImpl) setHugePagesConfig(configs map[v1.PodQOSClass]*CgroupConfig) error { - for _, v := range configs { - if err := m.setHugePagesUnbounded(v); err != nil { - return err - } - } - return nil -} - -func (m *qosContainerManagerImpl) setCPUCgroupConfig(configs map[v1.PodQOSClass]*CgroupConfig) error { - pods := m.activePods() - burstablePodCPURequest := int64(0) - reuseReqs := make(v1.ResourceList, 4) - for i := range pods { - pod := pods[i] - qosClass := v1qos.GetPodQOS(pod) - if qosClass != v1.PodQOSBurstable { - // we only care about the burstable qos tier - continue - } - req := resource.PodRequests(pod, resource.PodResourcesOptions{ - Reuse: reuseReqs, - // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.PodLevelResources), - }) - if request, found := req[v1.ResourceCPU]; found { - burstablePodCPURequest += request.MilliValue() - } - } - - // make sure best effort is always 2 shares - bestEffortCPUShares := uint64(MinShares) - configs[v1.PodQOSBestEffort].ResourceParameters.CPUShares = &bestEffortCPUShares - - // set burstable shares based on current observe state - burstableCPUShares := MilliCPUToShares(burstablePodCPURequest) - configs[v1.PodQOSBurstable].ResourceParameters.CPUShares = &burstableCPUShares - return nil -} - -// getQoSMemoryRequests sums and returns the memory request of all pods for -// guaranteed and burstable qos classes. -func (m *qosContainerManagerImpl) getQoSMemoryRequests() map[v1.PodQOSClass]int64 { - qosMemoryRequests := map[v1.PodQOSClass]int64{ - v1.PodQOSGuaranteed: 0, - v1.PodQOSBurstable: 0, - } - - // Sum the pod limits for pods in each QOS class - pods := m.activePods() - reuseReqs := make(v1.ResourceList, 4) - for _, pod := range pods { - podMemoryRequest := int64(0) - qosClass := v1qos.GetPodQOS(pod) - if qosClass == v1.PodQOSBestEffort { - // limits are not set for Best Effort pods - continue - } - req := resource.PodRequests(pod, resource.PodResourcesOptions{Reuse: reuseReqs}) - if request, found := req[v1.ResourceMemory]; found { - podMemoryRequest += request.Value() - } - qosMemoryRequests[qosClass] += podMemoryRequest - } - - return qosMemoryRequests -} - -// setMemoryReserve sums the memory limits of all pods in a QOS class, -// calculates QOS class memory limits, and set those limits in the -// CgroupConfig for each QOS class. -func (m *qosContainerManagerImpl) setMemoryReserve(configs map[v1.PodQOSClass]*CgroupConfig, percentReserve int64) { - qosMemoryRequests := m.getQoSMemoryRequests() - - resources := m.getNodeAllocatable() - allocatableResource, ok := resources[v1.ResourceMemory] - if !ok { - klog.V(2).InfoS("Allocatable memory value could not be determined, not setting QoS memory limits") - return - } - allocatable := allocatableResource.Value() - if allocatable == 0 { - klog.V(2).InfoS("Allocatable memory reported as 0, might be in standalone mode, not setting QoS memory limits") - return - } - - for qos, limits := range qosMemoryRequests { - klog.V(2).InfoS("QoS pod memory limit", "qos", qos, "limits", limits, "percentReserve", percentReserve) - } - - // Calculate QOS memory limits - burstableLimit := allocatable - (qosMemoryRequests[v1.PodQOSGuaranteed] * percentReserve / 100) - bestEffortLimit := burstableLimit - (qosMemoryRequests[v1.PodQOSBurstable] * percentReserve / 100) - configs[v1.PodQOSBurstable].ResourceParameters.Memory = &burstableLimit - configs[v1.PodQOSBestEffort].ResourceParameters.Memory = &bestEffortLimit -} - -// retrySetMemoryReserve checks for any QoS cgroups over the limit -// that was attempted to be set in the first Update() and adjusts -// their memory limit to the usage to prevent further growth. -func (m *qosContainerManagerImpl) retrySetMemoryReserve(configs map[v1.PodQOSClass]*CgroupConfig, percentReserve int64) { - // Unreclaimable memory usage may already exceeded the desired limit - // Attempt to set the limit near the current usage to put pressure - // on the cgroup and prevent further growth. - for qos, config := range configs { - usage, err := m.cgroupManager.MemoryUsage(config.Name) - if err != nil { - klog.V(2).InfoS("Failed to get resource stats", "err", err) - return - } - - // Because there is no good way to determine of the original Update() - // on the memory resource was successful, we determine failure of the - // first attempt by checking if the usage is above the limit we attempt - // to set. If it is, we assume the first attempt to set the limit failed - // and try again setting the limit to the usage. Otherwise we leave - // the CgroupConfig as is. - if configs[qos].ResourceParameters.Memory != nil && usage > *configs[qos].ResourceParameters.Memory { - configs[qos].ResourceParameters.Memory = &usage - } - } -} - -// setMemoryQoS sums the memory requests of all pods in the Burstable class, -// and set the sum memory as the memory.min in the Unified field of CgroupConfig. -func (m *qosContainerManagerImpl) setMemoryQoS(configs map[v1.PodQOSClass]*CgroupConfig) { - qosMemoryRequests := m.getQoSMemoryRequests() - - // Calculate the memory.min: - // for burstable(/kubepods/burstable): sum of all burstable pods - // for guaranteed(/kubepods): sum of all guaranteed and burstable pods - burstableMin := qosMemoryRequests[v1.PodQOSBurstable] - guaranteedMin := qosMemoryRequests[v1.PodQOSGuaranteed] + burstableMin - - if burstableMin > 0 { - if configs[v1.PodQOSBurstable].ResourceParameters.Unified == nil { - configs[v1.PodQOSBurstable].ResourceParameters.Unified = make(map[string]string) - } - configs[v1.PodQOSBurstable].ResourceParameters.Unified[Cgroup2MemoryMin] = strconv.FormatInt(burstableMin, 10) - klog.V(4).InfoS("MemoryQoS config for qos", "qos", v1.PodQOSBurstable, "memoryMin", burstableMin) - } - - if guaranteedMin > 0 { - if configs[v1.PodQOSGuaranteed].ResourceParameters.Unified == nil { - configs[v1.PodQOSGuaranteed].ResourceParameters.Unified = make(map[string]string) - } - configs[v1.PodQOSGuaranteed].ResourceParameters.Unified[Cgroup2MemoryMin] = strconv.FormatInt(guaranteedMin, 10) - klog.V(4).InfoS("MemoryQoS config for qos", "qos", v1.PodQOSGuaranteed, "memoryMin", guaranteedMin) - } -} - -func (m *qosContainerManagerImpl) UpdateCgroups() error { - m.Lock() - defer m.Unlock() - - qosConfigs := map[v1.PodQOSClass]*CgroupConfig{ - v1.PodQOSGuaranteed: { - Name: m.qosContainersInfo.Guaranteed, - ResourceParameters: &ResourceConfig{}, - }, - v1.PodQOSBurstable: { - Name: m.qosContainersInfo.Burstable, - ResourceParameters: &ResourceConfig{}, - }, - v1.PodQOSBestEffort: { - Name: m.qosContainersInfo.BestEffort, - ResourceParameters: &ResourceConfig{}, - }, - } - - // update the qos level cgroup settings for cpu shares - if err := m.setCPUCgroupConfig(qosConfigs); err != nil { - return err - } - - // update the qos level cgroup settings for huge pages (ensure they remain unbounded) - if err := m.setHugePagesConfig(qosConfigs); err != nil { - return err - } - - // update the qos level cgrougs v2 settings of memory qos if feature enabled - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.MemoryQoS) && - libcontainercgroups.IsCgroup2UnifiedMode() { - m.setMemoryQoS(qosConfigs) - } - - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.QOSReserved) { - for resource, percentReserve := range m.qosReserved { - switch resource { - case v1.ResourceMemory: - m.setMemoryReserve(qosConfigs, percentReserve) - } - } - - updateSuccess := true - for _, config := range qosConfigs { - err := m.cgroupManager.Update(config) - if err != nil { - updateSuccess = false - } - } - if updateSuccess { - klog.V(4).InfoS("Updated QoS cgroup configuration") - return nil - } - - // If the resource can adjust the ResourceConfig to increase likelihood of - // success, call the adjustment function here. Otherwise, the Update() will - // be called again with the same values. - for resource, percentReserve := range m.qosReserved { - switch resource { - case v1.ResourceMemory: - m.retrySetMemoryReserve(qosConfigs, percentReserve) - } - } - } - - for _, config := range qosConfigs { - err := m.cgroupManager.Update(config) - if err != nil { - klog.ErrorS(err, "Failed to update QoS cgroup configuration") - return err - } - } - - klog.V(4).InfoS("Updated QoS cgroup configuration") - return nil -} - -type qosContainerManagerNoop struct { - cgroupRoot CgroupName -} - -var _ QOSContainerManager = &qosContainerManagerNoop{} - -func (m *qosContainerManagerNoop) GetQOSContainersInfo() QOSContainersInfo { - return QOSContainersInfo{} -} - -func (m *qosContainerManagerNoop) Start(_ func() v1.ResourceList, _ ActivePodsFunc) error { - return nil -} - -func (m *qosContainerManagerNoop) UpdateCgroups() error { - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates/updates.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates/updates.go deleted file mode 100644 index 3bf0155a3..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates/updates.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package resourceupdates - -// Update is a struct that represents an update to a pod when -// the resource changes it's status. -// Later we may need to add fields like container name, resource name, and a new status. -type Update struct { - // PodUID is the UID of the pod which status needs to be updated. - PodUIDs []string -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/OWNERS b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/OWNERS deleted file mode 100644 index f0df77f40..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/OWNERS +++ /dev/null @@ -1,9 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - derekwaynecarr - - klueska -reviewers: [] -emeritus_approvers: - - ConnorDoyle - - lmdaly diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go deleted file mode 100644 index 3d029adb6..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask/bitmask.go +++ /dev/null @@ -1,222 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package bitmask - -import ( - "fmt" - "math/bits" - "strconv" -) - -// BitMask interface allows hint providers to create BitMasks for TopologyHints -type BitMask interface { - Add(bits ...int) error - Remove(bits ...int) error - And(masks ...BitMask) - Or(masks ...BitMask) - Clear() - Fill() - IsEqual(mask BitMask) bool - IsEmpty() bool - IsSet(bit int) bool - AnySet(bits []int) bool - IsNarrowerThan(mask BitMask) bool - IsLessThan(mask BitMask) bool - IsGreaterThan(mask BitMask) bool - String() string - Count() int - GetBits() []int -} - -type bitMask uint64 - -// NewEmptyBitMask creates a new, empty BitMask -func NewEmptyBitMask() BitMask { - s := bitMask(0) - return &s -} - -// NewBitMask creates a new BitMask -func NewBitMask(bits ...int) (BitMask, error) { - s := bitMask(0) - err := (&s).Add(bits...) - if err != nil { - return nil, err - } - return &s, nil -} - -// Add adds the bits with topology affinity to the BitMask -func (s *bitMask) Add(bits ...int) error { - mask := *s - for _, i := range bits { - if i < 0 || i >= 64 { - return fmt.Errorf("bit number must be in range 0-63") - } - mask |= 1 << uint64(i) - } - *s = mask - return nil -} - -// Remove removes specified bits from BitMask -func (s *bitMask) Remove(bits ...int) error { - mask := *s - for _, i := range bits { - if i < 0 || i >= 64 { - return fmt.Errorf("bit number must be in range 0-63") - } - mask &^= 1 << uint64(i) - } - *s = mask - return nil -} - -// And performs and operation on all bits in masks -func (s *bitMask) And(masks ...BitMask) { - for _, m := range masks { - *s &= *m.(*bitMask) - } -} - -// Or performs or operation on all bits in masks -func (s *bitMask) Or(masks ...BitMask) { - for _, m := range masks { - *s |= *m.(*bitMask) - } -} - -// Clear resets all bits in mask to zero -func (s *bitMask) Clear() { - *s = 0 -} - -// Fill sets all bits in mask to one -func (s *bitMask) Fill() { - *s = bitMask(^uint64(0)) -} - -// IsEmpty checks mask to see if all bits are zero -func (s *bitMask) IsEmpty() bool { - return *s == 0 -} - -// IsSet checks bit in mask to see if bit is set to one -func (s *bitMask) IsSet(bit int) bool { - if bit < 0 || bit >= 64 { - return false - } - return (*s & (1 << uint64(bit))) > 0 -} - -// AnySet checks bit in mask to see if any provided bit is set to one -func (s *bitMask) AnySet(bits []int) bool { - for _, b := range bits { - if s.IsSet(b) { - return true - } - } - return false -} - -// IsEqual checks if masks are equal -func (s *bitMask) IsEqual(mask BitMask) bool { - return *s == *mask.(*bitMask) -} - -// IsNarrowerThan checks if one mask is narrower than another. -// -// A mask is said to be "narrower" than another if it has lets bits set. If the -// same number of bits are set in both masks, then the mask with more -// lower-numbered bits set wins out. -func (s *bitMask) IsNarrowerThan(mask BitMask) bool { - if s.Count() == mask.Count() { - return s.IsLessThan(mask) - } - return s.Count() < mask.Count() -} - -// IsLessThan checks which bitmask has more lower-numbered bits set. -func (s *bitMask) IsLessThan(mask BitMask) bool { - return *s < *mask.(*bitMask) -} - -// IsGreaterThan checks which bitmask has more higher-numbered bits set. -func (s *bitMask) IsGreaterThan(mask BitMask) bool { - return *s > *mask.(*bitMask) -} - -// String converts mask to string -func (s *bitMask) String() string { - grouping := 2 - for shift := 64 - grouping; shift > 0; shift -= grouping { - if *s > (1 << uint(shift)) { - return fmt.Sprintf("%0"+strconv.Itoa(shift+grouping)+"b", *s) - } - } - return fmt.Sprintf("%0"+strconv.Itoa(grouping)+"b", *s) -} - -// Count counts number of bits in mask set to one -func (s *bitMask) Count() int { - return bits.OnesCount64(uint64(*s)) -} - -// Getbits returns each bit number with bits set to one -func (s *bitMask) GetBits() []int { - var bits []int - for i := uint64(0); i < 64; i++ { - if (*s & (1 << i)) > 0 { - bits = append(bits, int(i)) - } - } - return bits -} - -// And is a package level implementation of 'and' between first and masks -func And(first BitMask, masks ...BitMask) BitMask { - s := *first.(*bitMask) - s.And(masks...) - return &s -} - -// Or is a package level implementation of 'or' between first and masks -func Or(first BitMask, masks ...BitMask) BitMask { - s := *first.(*bitMask) - s.Or(masks...) - return &s -} - -// IterateBitMasks iterates all possible masks from a list of bits, -// issuing a callback on each mask. -func IterateBitMasks(bits []int, callback func(BitMask)) { - var iterate func(bits, accum []int, size int) - iterate = func(bits, accum []int, size int) { - if len(accum) == size { - mask, _ := NewBitMask(accum...) - callback(mask) - return - } - for i := range bits { - iterate(bits[i+1:], append(accum, bits[i]), size) - } - } - - for i := 1; i <= len(bits); i++ { - iterate(bits, []int{}, i) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go deleted file mode 100644 index 19b07a719..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/fake_topology_manager.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/admission" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" -) - -type fakeManager struct { - hint *TopologyHint - policy Policy -} - -// NewFakeManager returns an instance of FakeManager -func NewFakeManager() Manager { - klog.InfoS("NewFakeManager") - return &fakeManager{} -} - -// NewFakeManagerWithHint returns an instance of fake topology manager with specified topology hints -func NewFakeManagerWithHint(hint *TopologyHint) Manager { - klog.InfoS("NewFakeManagerWithHint") - return &fakeManager{ - hint: hint, - policy: NewNonePolicy(), - } -} - -// NewFakeManagerWithPolicy returns an instance of fake topology manager with specified policy -func NewFakeManagerWithPolicy(policy Policy) Manager { - klog.InfoS("NewFakeManagerWithPolicy", "policy", policy.Name()) - return &fakeManager{ - policy: policy, - } -} - -func (m *fakeManager) GetAffinity(podUID string, containerName string) TopologyHint { - klog.InfoS("GetAffinity", "podUID", podUID, "containerName", containerName) - if m.hint == nil { - return TopologyHint{} - } - - return *m.hint -} - -func (m *fakeManager) GetPolicy() Policy { - return m.policy -} - -func (m *fakeManager) AddHintProvider(h HintProvider) { - klog.InfoS("AddHintProvider", "hintProvider", h) -} - -func (m *fakeManager) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) { - klog.InfoS("AddContainer", "pod", klog.KObj(pod), "containerName", container.Name, "containerID", containerID) -} - -func (m *fakeManager) RemoveContainer(containerID string) error { - klog.InfoS("RemoveContainer", "containerID", containerID) - return nil -} - -func (m *fakeManager) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult { - klog.InfoS("Topology Admit Handler") - return admission.GetPodAdmitResult(nil) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/numa_info.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/numa_info.go deleted file mode 100644 index c69772667..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/numa_info.go +++ /dev/null @@ -1,109 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "fmt" - - cadvisorapi "github.com/google/cadvisor/info/v1" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" -) - -type NUMADistances map[int][]uint64 - -type NUMAInfo struct { - Nodes []int - NUMADistances NUMADistances -} - -func NewNUMAInfo(topology []cadvisorapi.Node, opts PolicyOptions) (*NUMAInfo, error) { - var numaNodes []int - distances := map[int][]uint64{} - for _, node := range topology { - numaNodes = append(numaNodes, node.Id) - - var nodeDistance []uint64 - if opts.PreferClosestNUMA { - nodeDistance = node.Distances - if nodeDistance == nil { - return nil, fmt.Errorf("error getting NUMA distances from cadvisor") - } - } - distances[node.Id] = nodeDistance - } - - numaInfo := &NUMAInfo{ - Nodes: numaNodes, - NUMADistances: distances, - } - - return numaInfo, nil -} - -func (n *NUMAInfo) Narrowest(m1 bitmask.BitMask, m2 bitmask.BitMask) bitmask.BitMask { - if m1.IsNarrowerThan(m2) { - return m1 - } - return m2 -} - -func (n *NUMAInfo) Closest(m1 bitmask.BitMask, m2 bitmask.BitMask) bitmask.BitMask { - // If the length of both bitmasks aren't the same, choose the one that is narrowest. - if m1.Count() != m2.Count() { - return n.Narrowest(m1, m2) - } - - m1Distance := n.NUMADistances.CalculateAverageFor(m1) - m2Distance := n.NUMADistances.CalculateAverageFor(m2) - // If average distance is the same, take bitmask with more lower-number bits set. - if m1Distance == m2Distance { - if m1.IsLessThan(m2) { - return m1 - } - return m2 - } - - // Otherwise, return the bitmask with the shortest average distance between NUMA nodes. - if m1Distance < m2Distance { - return m1 - } - - return m2 -} - -func (n NUMAInfo) DefaultAffinityMask() bitmask.BitMask { - defaultAffinity, _ := bitmask.NewBitMask(n.Nodes...) - return defaultAffinity -} - -func (d NUMADistances) CalculateAverageFor(bm bitmask.BitMask) float64 { - // This should never happen, but just in case make sure we do not divide by zero. - if bm.Count() == 0 { - return 0 - } - - var count float64 = 0 - var sum float64 = 0 - for _, node1 := range bm.GetBits() { - for _, node2 := range bm.GetBits() { - sum += float64(d[node1][node2]) - count++ - } - } - - return sum / count -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy.go deleted file mode 100644 index 80e9292ae..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy.go +++ /dev/null @@ -1,361 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" -) - -// Policy interface for Topology Manager Pod Admit Result -type Policy interface { - // Returns Policy Name - Name() string - // Returns a merged TopologyHint based on input from hint providers - // and a Pod Admit Handler Response based on hints and policy type - Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) -} - -// IsAlignmentGuaranteed return true if the given policy guarantees that either -// the compute resources will be allocated within a NUMA boundary, or the allocation will fail at all. -func IsAlignmentGuaranteed(p Policy) bool { - // We are abusing the name, but atm this matches almost 1:1 the policy name - // so we are not adding new fields for now. - return p.Name() == PolicySingleNumaNode -} - -// Merge a TopologyHints permutation to a single hint by performing a bitwise-AND -// of their affinity masks. The hint shall be preferred if all hits in the permutation -// are preferred. -func mergePermutation(defaultAffinity bitmask.BitMask, permutation []TopologyHint) TopologyHint { - // Get the NUMANodeAffinity from each hint in the permutation and see if any - // of them encode unpreferred allocations. - preferred := true - var numaAffinities []bitmask.BitMask - for _, hint := range permutation { - // Only consider hints that have an actual NUMANodeAffinity set. - if hint.NUMANodeAffinity != nil { - numaAffinities = append(numaAffinities, hint.NUMANodeAffinity) - // Only mark preferred if all affinities are equal. - if !hint.NUMANodeAffinity.IsEqual(numaAffinities[0]) { - preferred = false - } - } - // Only mark preferred if all affinities are preferred. - if !hint.Preferred { - preferred = false - } - } - - // Merge the affinities using a bitwise-and operation. - mergedAffinity := bitmask.And(defaultAffinity, numaAffinities...) - // Build a mergedHint from the merged affinity mask, setting preferred as - // appropriate based on the logic above. - return TopologyHint{mergedAffinity, preferred} -} - -func filterProvidersHints(providersHints []map[string][]TopologyHint) [][]TopologyHint { - // Loop through all hint providers and save an accumulated list of the - // hints returned by each hint provider. If no hints are provided, assume - // that provider has no preference for topology-aware allocation. - var allProviderHints [][]TopologyHint - for _, hints := range providersHints { - // If hints is nil, insert a single, preferred any-numa hint into allProviderHints. - if len(hints) == 0 { - klog.InfoS("Hint Provider has no preference for NUMA affinity with any resource") - allProviderHints = append(allProviderHints, []TopologyHint{{nil, true}}) - continue - } - - // Otherwise, accumulate the hints for each resource type into allProviderHints. - for resource := range hints { - if hints[resource] == nil { - klog.InfoS("Hint Provider has no preference for NUMA affinity with resource", "resource", resource) - allProviderHints = append(allProviderHints, []TopologyHint{{nil, true}}) - continue - } - - if len(hints[resource]) == 0 { - klog.InfoS("Hint Provider has no possible NUMA affinities for resource", "resource", resource) - allProviderHints = append(allProviderHints, []TopologyHint{{nil, false}}) - continue - } - - allProviderHints = append(allProviderHints, hints[resource]) - } - } - return allProviderHints -} - -func narrowestHint(hints []TopologyHint) *TopologyHint { - if len(hints) == 0 { - return nil - } - var narrowestHint *TopologyHint - for i := range hints { - if hints[i].NUMANodeAffinity == nil { - continue - } - if narrowestHint == nil { - narrowestHint = &hints[i] - } - if hints[i].NUMANodeAffinity.IsNarrowerThan(narrowestHint.NUMANodeAffinity) { - narrowestHint = &hints[i] - } - } - return narrowestHint -} - -func maxOfMinAffinityCounts(filteredHints [][]TopologyHint) int { - maxOfMinCount := 0 - for _, resourceHints := range filteredHints { - narrowestHint := narrowestHint(resourceHints) - if narrowestHint == nil { - continue - } - if narrowestHint.NUMANodeAffinity.Count() > maxOfMinCount { - maxOfMinCount = narrowestHint.NUMANodeAffinity.Count() - } - } - return maxOfMinCount -} - -type HintMerger struct { - NUMAInfo *NUMAInfo - Hints [][]TopologyHint - // Set bestNonPreferredAffinityCount to help decide which affinity mask is - // preferred amongst all non-preferred hints. We calculate this value as - // the maximum of the minimum affinity counts supplied for any given hint - // provider. In other words, prefer a hint that has an affinity mask that - // includes all of the NUMA nodes from the provider that requires the most - // NUMA nodes to satisfy its allocation. - BestNonPreferredAffinityCount int - CompareNUMAAffinityMasks func(candidate *TopologyHint, current *TopologyHint) (best *TopologyHint) -} - -func NewHintMerger(numaInfo *NUMAInfo, hints [][]TopologyHint, policyName string, opts PolicyOptions) HintMerger { - compareNumaAffinityMasks := func(current, candidate *TopologyHint) *TopologyHint { - // If current and candidate bitmasks are the same, prefer current hint. - if candidate.NUMANodeAffinity.IsEqual(current.NUMANodeAffinity) { - return current - } - - // Otherwise compare the hints, based on the policy options provided - var best bitmask.BitMask - if (policyName != PolicySingleNumaNode) && opts.PreferClosestNUMA { - best = numaInfo.Closest(current.NUMANodeAffinity, candidate.NUMANodeAffinity) - } else { - best = numaInfo.Narrowest(current.NUMANodeAffinity, candidate.NUMANodeAffinity) - } - if best.IsEqual(current.NUMANodeAffinity) { - return current - } - return candidate - } - - merger := HintMerger{ - NUMAInfo: numaInfo, - Hints: hints, - BestNonPreferredAffinityCount: maxOfMinAffinityCounts(hints), - CompareNUMAAffinityMasks: compareNumaAffinityMasks, - } - - return merger -} - -func (m HintMerger) compare(current *TopologyHint, candidate *TopologyHint) *TopologyHint { - // Only consider candidates that result in a NUMANodeAffinity > 0 to - // replace the current bestHint. - if candidate.NUMANodeAffinity.Count() == 0 { - return current - } - - // If no current bestHint is set, return the candidate as the bestHint. - if current == nil { - return candidate - } - - // If the current bestHint is non-preferred and the candidate hint is - // preferred, always choose the preferred hint over the non-preferred one. - if !current.Preferred && candidate.Preferred { - return candidate - } - - // If the current bestHint is preferred and the candidate hint is - // non-preferred, never update the bestHint, regardless of how - // the candidate hint's affinity mask compares to the current - // hint's affinity mask. - if current.Preferred && !candidate.Preferred { - return current - } - - // If the current bestHint and the candidate hint are both preferred, - // then only consider fitter NUMANodeAffinity - if current.Preferred && candidate.Preferred { - return m.CompareNUMAAffinityMasks(current, candidate) - - } - - // The only case left is if the current best bestHint and the candidate - // hint are both non-preferred. In this case, try and find a hint whose - // affinity count is as close to (but not higher than) the - // bestNonPreferredAffinityCount as possible. To do this we need to - // consider the following cases and react accordingly: - // - // 1. current.NUMANodeAffinity.Count() > bestNonPreferredAffinityCount - // 2. current.NUMANodeAffinity.Count() == bestNonPreferredAffinityCount - // 3. current.NUMANodeAffinity.Count() < bestNonPreferredAffinityCount - // - // For case (1), the current bestHint is larger than the - // bestNonPreferredAffinityCount, so updating to fitter mergeHint - // is preferred over staying where we are. - // - // For case (2), the current bestHint is equal to the - // bestNonPreferredAffinityCount, so we would like to stick with what - // we have *unless* the candidate hint is also equal to - // bestNonPreferredAffinityCount and it is fitter. - // - // For case (3), the current bestHint is less than - // bestNonPreferredAffinityCount, so we would like to creep back up to - // bestNonPreferredAffinityCount as close as we can. There are three - // cases to consider here: - // - // 3a. candidate.NUMANodeAffinity.Count() > bestNonPreferredAffinityCount - // 3b. candidate.NUMANodeAffinity.Count() == bestNonPreferredAffinityCount - // 3c. candidate.NUMANodeAffinity.Count() < bestNonPreferredAffinityCount - // - // For case (3a), we just want to stick with the current bestHint - // because choosing a new hint that is greater than - // bestNonPreferredAffinityCount would be counter-productive. - // - // For case (3b), we want to immediately update bestHint to the - // candidate hint, making it now equal to bestNonPreferredAffinityCount. - // - // For case (3c), we know that *both* the current bestHint and the - // candidate hint are less than bestNonPreferredAffinityCount, so we - // want to choose one that brings us back up as close to - // bestNonPreferredAffinityCount as possible. There are three cases to - // consider here: - // - // 3ca. candidate.NUMANodeAffinity.Count() > current.NUMANodeAffinity.Count() - // 3cb. candidate.NUMANodeAffinity.Count() < current.NUMANodeAffinity.Count() - // 3cc. candidate.NUMANodeAffinity.Count() == current.NUMANodeAffinity.Count() - // - // For case (3ca), we want to immediately update bestHint to the - // candidate hint because that will bring us closer to the (higher) - // value of bestNonPreferredAffinityCount. - // - // For case (3cb), we want to stick with the current bestHint because - // choosing the candidate hint would strictly move us further away from - // the bestNonPreferredAffinityCount. - // - // Finally, for case (3cc), we know that the current bestHint and the - // candidate hint are equal, so we simply choose the fitter of the 2. - - // Case 1 - if current.NUMANodeAffinity.Count() > m.BestNonPreferredAffinityCount { - return m.CompareNUMAAffinityMasks(current, candidate) - } - // Case 2 - if current.NUMANodeAffinity.Count() == m.BestNonPreferredAffinityCount { - if candidate.NUMANodeAffinity.Count() != m.BestNonPreferredAffinityCount { - return current - } - return m.CompareNUMAAffinityMasks(current, candidate) - } - // Case 3a - if candidate.NUMANodeAffinity.Count() > m.BestNonPreferredAffinityCount { - return current - } - // Case 3b - if candidate.NUMANodeAffinity.Count() == m.BestNonPreferredAffinityCount { - return candidate - } - - // Case 3ca - if candidate.NUMANodeAffinity.Count() > current.NUMANodeAffinity.Count() { - return candidate - } - // Case 3cb - if candidate.NUMANodeAffinity.Count() < current.NUMANodeAffinity.Count() { - return current - } - - // Case 3cc - return m.CompareNUMAAffinityMasks(current, candidate) - -} - -func (m HintMerger) Merge() TopologyHint { - defaultAffinity := m.NUMAInfo.DefaultAffinityMask() - - var bestHint *TopologyHint - iterateAllProviderTopologyHints(m.Hints, func(permutation []TopologyHint) { - // Get the NUMANodeAffinity from each hint in the permutation and see if any - // of them encode unpreferred allocations. - mergedHint := mergePermutation(defaultAffinity, permutation) - - // Compare the current bestHint with the candidate mergedHint and - // update bestHint if appropriate. - bestHint = m.compare(bestHint, &mergedHint) - }) - - if bestHint == nil { - bestHint = &TopologyHint{defaultAffinity, false} - } - - return *bestHint -} - -// Iterate over all permutations of hints in 'allProviderHints [][]TopologyHint'. -// -// This procedure is implemented as a recursive function over the set of hints -// in 'allproviderHints[i]'. It applies the function 'callback' to each -// permutation as it is found. It is the equivalent of: -// -// for i := 0; i < len(providerHints[0]); i++ -// -// for j := 0; j < len(providerHints[1]); j++ -// for k := 0; k < len(providerHints[2]); k++ -// ... -// for z := 0; z < len(providerHints[-1]); z++ -// permutation := []TopologyHint{ -// providerHints[0][i], -// providerHints[1][j], -// providerHints[2][k], -// ... -// providerHints[-1][z] -// } -// callback(permutation) -func iterateAllProviderTopologyHints(allProviderHints [][]TopologyHint, callback func([]TopologyHint)) { - // Internal helper function to accumulate the permutation before calling the callback. - var iterate func(i int, accum []TopologyHint) - iterate = func(i int, accum []TopologyHint) { - // Base case: we have looped through all providers and have a full permutation. - if i == len(allProviderHints) { - callback(accum) - return - } - - // Loop through all hints for provider 'i', and recurse to build the - // permutation of this hint with all hints from providers 'i++'. - for j := range allProviderHints[i] { - iterate(i+1, append(accum, allProviderHints[i][j])) - } - } - iterate(0, []TopologyHint{}) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_best_effort.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_best_effort.go deleted file mode 100644 index 5cedad3da..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_best_effort.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -type bestEffortPolicy struct { - // numaInfo represents list of NUMA Nodes available on the underlying machine and distances between them - numaInfo *NUMAInfo - opts PolicyOptions -} - -var _ Policy = &bestEffortPolicy{} - -// PolicyBestEffort policy name. -const PolicyBestEffort string = "best-effort" - -// NewBestEffortPolicy returns best-effort policy. -func NewBestEffortPolicy(numaInfo *NUMAInfo, opts PolicyOptions) Policy { - return &bestEffortPolicy{numaInfo: numaInfo, opts: opts} -} - -func (p *bestEffortPolicy) Name() string { - return PolicyBestEffort -} - -func (p *bestEffortPolicy) canAdmitPodResult(hint *TopologyHint) bool { - return true -} - -func (p *bestEffortPolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) { - filteredHints := filterProvidersHints(providersHints) - merger := NewHintMerger(p.numaInfo, filteredHints, p.Name(), p.opts) - bestHint := merger.Merge() - admit := p.canAdmitPodResult(&bestHint) - return bestHint, admit -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_none.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_none.go deleted file mode 100644 index 271f9dde7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_none.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -type nonePolicy struct{} - -var _ Policy = &nonePolicy{} - -// PolicyNone policy name. -const PolicyNone string = "none" - -// NewNonePolicy returns none policy. -func NewNonePolicy() Policy { - return &nonePolicy{} -} - -func (p *nonePolicy) Name() string { - return PolicyNone -} - -func (p *nonePolicy) canAdmitPodResult(hint *TopologyHint) bool { - return true -} - -func (p *nonePolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) { - return TopologyHint{}, p.canAdmitPodResult(nil) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_options.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_options.go deleted file mode 100644 index 5490aba11..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_options.go +++ /dev/null @@ -1,105 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "fmt" - "strconv" - - "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - kubefeatures "k8s.io/kubernetes/pkg/features" -) - -const ( - PreferClosestNUMANodes string = "prefer-closest-numa-nodes" - MaxAllowableNUMANodes string = "max-allowable-numa-nodes" -) - -var ( - alphaOptions = sets.New[string]() - betaOptions = sets.New[string]( - MaxAllowableNUMANodes, - ) - stableOptions = sets.New[string]( - PreferClosestNUMANodes, - ) -) - -func CheckPolicyOptionAvailable(option string) error { - if !alphaOptions.Has(option) && !betaOptions.Has(option) && !stableOptions.Has(option) { - return fmt.Errorf("unknown Topology Manager Policy option: %q", option) - } - - if alphaOptions.Has(option) && !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.TopologyManagerPolicyAlphaOptions) { - return fmt.Errorf("topology manager policy alpha-level options not enabled, but option %q provided", option) - } - - if betaOptions.Has(option) && !utilfeature.DefaultFeatureGate.Enabled(kubefeatures.TopologyManagerPolicyBetaOptions) { - return fmt.Errorf("topology manager policy beta-level options not enabled, but option %q provided", option) - } - - return nil -} - -type PolicyOptions struct { - PreferClosestNUMA bool - MaxAllowableNUMANodes int -} - -func NewPolicyOptions(policyOptions map[string]string) (PolicyOptions, error) { - opts := PolicyOptions{ - // Set MaxAllowableNUMANodes to the default. This will be overwritten - // if the user has specified a policy option for MaxAllowableNUMANodes. - MaxAllowableNUMANodes: defaultMaxAllowableNUMANodes, - } - - for name, value := range policyOptions { - if err := CheckPolicyOptionAvailable(name); err != nil { - return opts, err - } - - switch name { - case PreferClosestNUMANodes: - optValue, err := strconv.ParseBool(value) - if err != nil { - return opts, fmt.Errorf("bad value for option %q: %w", name, err) - } - opts.PreferClosestNUMA = optValue - case MaxAllowableNUMANodes: - optValue, err := strconv.Atoi(value) - if err != nil { - return opts, fmt.Errorf("unable to convert policy option to integer %q: %w", name, err) - } - - if optValue < defaultMaxAllowableNUMANodes { - return opts, fmt.Errorf("the minimum value of %q should not be less than %v", name, defaultMaxAllowableNUMANodes) - } - - if optValue > defaultMaxAllowableNUMANodes { - klog.InfoS("WARNING: the value of max-allowable-numa-nodes is more than the default recommended value", "max-allowable-numa-nodes", optValue, "defaultMaxAllowableNUMANodes", defaultMaxAllowableNUMANodes) - } - opts.MaxAllowableNUMANodes = optValue - default: - // this should never be reached, we already detect unknown options, - // but we keep it as further safety. - return opts, fmt.Errorf("unsupported topologymanager option: %q (%s)", name, value) - } - } - return opts, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_restricted.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_restricted.go deleted file mode 100644 index 88422b008..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_restricted.go +++ /dev/null @@ -1,47 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -type restrictedPolicy struct { - bestEffortPolicy -} - -var _ Policy = &restrictedPolicy{} - -// PolicyRestricted policy name. -const PolicyRestricted string = "restricted" - -// NewRestrictedPolicy returns restricted policy. -func NewRestrictedPolicy(numaInfo *NUMAInfo, opts PolicyOptions) Policy { - return &restrictedPolicy{bestEffortPolicy{numaInfo: numaInfo, opts: opts}} -} - -func (p *restrictedPolicy) Name() string { - return PolicyRestricted -} - -func (p *restrictedPolicy) canAdmitPodResult(hint *TopologyHint) bool { - return hint.Preferred -} - -func (p *restrictedPolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) { - filteredHints := filterProvidersHints(providersHints) - merger := NewHintMerger(p.numaInfo, filteredHints, p.Name(), p.opts) - bestHint := merger.Merge() - admit := p.canAdmitPodResult(&bestHint) - return bestHint, admit -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go deleted file mode 100644 index d865aa9f1..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/policy_single_numa_node.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -type singleNumaNodePolicy struct { - // numaInfo represents list of NUMA Nodes available on the underlying machine and distances between them - numaInfo *NUMAInfo - opts PolicyOptions -} - -var _ Policy = &singleNumaNodePolicy{} - -// PolicySingleNumaNode policy name. -const PolicySingleNumaNode string = "single-numa-node" - -// NewSingleNumaNodePolicy returns single-numa-node policy. -func NewSingleNumaNodePolicy(numaInfo *NUMAInfo, opts PolicyOptions) Policy { - return &singleNumaNodePolicy{numaInfo: numaInfo, opts: opts} -} - -func (p *singleNumaNodePolicy) Name() string { - return PolicySingleNumaNode -} - -func (p *singleNumaNodePolicy) canAdmitPodResult(hint *TopologyHint) bool { - return hint.Preferred -} - -// Return hints that have valid bitmasks with exactly one bit set. -func filterSingleNumaHints(allResourcesHints [][]TopologyHint) [][]TopologyHint { - var filteredResourcesHints [][]TopologyHint - for _, oneResourceHints := range allResourcesHints { - var filtered []TopologyHint - for _, hint := range oneResourceHints { - if hint.NUMANodeAffinity == nil && hint.Preferred { - filtered = append(filtered, hint) - } - if hint.NUMANodeAffinity != nil && hint.NUMANodeAffinity.Count() == 1 && hint.Preferred { - filtered = append(filtered, hint) - } - } - filteredResourcesHints = append(filteredResourcesHints, filtered) - } - return filteredResourcesHints -} - -func (p *singleNumaNodePolicy) Merge(providersHints []map[string][]TopologyHint) (TopologyHint, bool) { - filteredHints := filterProvidersHints(providersHints) - // Filter to only include don't cares and hints with a single NUMA node. - singleNumaHints := filterSingleNumaHints(filteredHints) - - merger := NewHintMerger(p.numaInfo, singleNumaHints, p.Name(), p.opts) - bestHint := merger.Merge() - - if bestHint.NUMANodeAffinity.IsEqual(p.numaInfo.DefaultAffinityMask()) { - bestHint = TopologyHint{nil, bestHint.Preferred} - } - - admit := p.canAdmitPodResult(&bestHint) - return bestHint, admit -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go deleted file mode 100644 index db3edd63e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope.go +++ /dev/null @@ -1,158 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "sync" - - "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/admission" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" -) - -const ( - // containerTopologyScope specifies the TopologyManagerScope per container. - containerTopologyScope = "container" - // podTopologyScope specifies the TopologyManagerScope per pod. - podTopologyScope = "pod" - // noneTopologyScope specifies the TopologyManagerScope when topologyPolicyName is none. - noneTopologyScope = "none" -) - -type podTopologyHints map[string]map[string]TopologyHint - -// Scope interface for Topology Manager -type Scope interface { - Name() string - GetPolicy() Policy - Admit(pod *v1.Pod) lifecycle.PodAdmitResult - // AddHintProvider adds a hint provider to manager to indicate the hint provider - // wants to be consoluted with when making topology hints - AddHintProvider(h HintProvider) - // AddContainer adds pod to Manager for tracking - AddContainer(pod *v1.Pod, container *v1.Container, containerID string) - // RemoveContainer removes pod from Manager tracking - RemoveContainer(containerID string) error - // Store is the interface for storing pod topology hints - Store -} - -type scope struct { - mutex sync.Mutex - name string - // Mapping of a Pods mapping of Containers and their TopologyHints - // Indexed by PodUID to ContainerName - podTopologyHints podTopologyHints - // The list of components registered with the Manager - hintProviders []HintProvider - // Topology Manager Policy - policy Policy - // Mapping of (PodUid, ContainerName) to ContainerID for Adding/Removing Pods from PodTopologyHints mapping - podMap containermap.ContainerMap -} - -func (s *scope) Name() string { - return s.name -} - -func (s *scope) getTopologyHints(podUID string, containerName string) TopologyHint { - s.mutex.Lock() - defer s.mutex.Unlock() - return s.podTopologyHints[podUID][containerName] -} - -func (s *scope) setTopologyHints(podUID string, containerName string, th TopologyHint) { - s.mutex.Lock() - defer s.mutex.Unlock() - - if s.podTopologyHints[podUID] == nil { - s.podTopologyHints[podUID] = make(map[string]TopologyHint) - } - s.podTopologyHints[podUID][containerName] = th -} - -func (s *scope) GetAffinity(podUID string, containerName string) TopologyHint { - return s.getTopologyHints(podUID, containerName) -} - -func (s *scope) GetPolicy() Policy { - return s.policy -} - -func (s *scope) AddHintProvider(h HintProvider) { - s.hintProviders = append(s.hintProviders, h) -} - -// It would be better to implement this function in topologymanager instead of scope -// but topologymanager do not track mapping anymore -func (s *scope) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) { - s.mutex.Lock() - defer s.mutex.Unlock() - - s.podMap.Add(string(pod.UID), container.Name, containerID) -} - -// It would be better to implement this function in topologymanager instead of scope -// but topologymanager do not track mapping anymore -func (s *scope) RemoveContainer(containerID string) error { - s.mutex.Lock() - defer s.mutex.Unlock() - - klog.InfoS("RemoveContainer", "containerID", containerID) - // Get the podUID and containerName associated with the containerID to be removed and remove it - podUIDString, containerName, err := s.podMap.GetContainerRef(containerID) - if err != nil { - return nil - } - s.podMap.RemoveByContainerID(containerID) - - // In cases where a container has been restarted, it's possible that the same podUID and - // containerName are already associated with a *different* containerID now. Only remove - // the TopologyHints associated with that podUID and containerName if this is not true - if _, err := s.podMap.GetContainerID(podUIDString, containerName); err != nil { - delete(s.podTopologyHints[podUIDString], containerName) - if len(s.podTopologyHints[podUIDString]) == 0 { - delete(s.podTopologyHints, podUIDString) - } - } - - return nil -} - -func (s *scope) admitPolicyNone(pod *v1.Pod) lifecycle.PodAdmitResult { - for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { - err := s.allocateAlignedResources(pod, &container) - if err != nil { - return admission.GetPodAdmitResult(err) - } - } - return admission.GetPodAdmitResult(nil) -} - -// It would be better to implement this function in topologymanager instead of scope -// but topologymanager do not track providers anymore -func (s *scope) allocateAlignedResources(pod *v1.Pod, container *v1.Container) error { - for _, provider := range s.hintProviders { - err := provider.Allocate(pod, container) - if err != nil { - return err - } - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go deleted file mode 100644 index 7c06c090c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_container.go +++ /dev/null @@ -1,93 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/admission" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" - "k8s.io/kubernetes/pkg/kubelet/metrics" -) - -type containerScope struct { - scope -} - -// Ensure containerScope implements Scope interface -var _ Scope = &containerScope{} - -// NewContainerScope returns a container scope. -func NewContainerScope(policy Policy) Scope { - return &containerScope{ - scope{ - name: containerTopologyScope, - podTopologyHints: podTopologyHints{}, - policy: policy, - podMap: containermap.NewContainerMap(), - }, - } -} - -func (s *containerScope) Admit(pod *v1.Pod) lifecycle.PodAdmitResult { - for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { - bestHint, admit := s.calculateAffinity(pod, &container) - klog.InfoS("Best TopologyHint", "bestHint", bestHint, "pod", klog.KObj(pod), "containerName", container.Name) - - if !admit { - if IsAlignmentGuaranteed(s.policy) { - metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedNUMANode).Inc() - } - metrics.TopologyManagerAdmissionErrorsTotal.Inc() - return admission.GetPodAdmitResult(&TopologyAffinityError{}) - } - klog.InfoS("Topology Affinity", "bestHint", bestHint, "pod", klog.KObj(pod), "containerName", container.Name) - s.setTopologyHints(string(pod.UID), container.Name, bestHint) - - err := s.allocateAlignedResources(pod, &container) - if err != nil { - metrics.TopologyManagerAdmissionErrorsTotal.Inc() - return admission.GetPodAdmitResult(err) - } - - if IsAlignmentGuaranteed(s.policy) { - klog.V(4).InfoS("Resource alignment at container scope guaranteed", "pod", klog.KObj(pod)) - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedNUMANode).Inc() - } - } - return admission.GetPodAdmitResult(nil) -} - -func (s *containerScope) accumulateProvidersHints(pod *v1.Pod, container *v1.Container) []map[string][]TopologyHint { - var providersHints []map[string][]TopologyHint - - for _, provider := range s.hintProviders { - // Get the TopologyHints for a Container from a provider. - hints := provider.GetTopologyHints(pod, container) - providersHints = append(providersHints, hints) - klog.InfoS("TopologyHints", "hints", hints, "pod", klog.KObj(pod), "containerName", container.Name) - } - return providersHints -} - -func (s *containerScope) calculateAffinity(pod *v1.Pod, container *v1.Container) (TopologyHint, bool) { - providersHints := s.accumulateProvidersHints(pod, container) - bestHint, admit := s.policy.Merge(providersHints) - klog.InfoS("ContainerTopologyHint", "bestHint", bestHint, "pod", klog.KObj(pod), "containerName", container.Name) - return bestHint, admit -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go deleted file mode 100644 index c82b19e1f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_none.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "k8s.io/api/core/v1" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" -) - -type noneScope struct { - scope -} - -// Ensure noneScope implements Scope interface -var _ Scope = &noneScope{} - -// NewNoneScope returns a none scope. -func NewNoneScope() Scope { - return &noneScope{ - scope{ - name: noneTopologyScope, - podTopologyHints: podTopologyHints{}, - policy: NewNonePolicy(), - podMap: containermap.NewContainerMap(), - }, - } -} - -func (s *noneScope) Admit(pod *v1.Pod) lifecycle.PodAdmitResult { - return s.admitPolicyNone(pod) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go deleted file mode 100644 index bcb421d61..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/scope_pod.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/admission" - "k8s.io/kubernetes/pkg/kubelet/cm/containermap" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" - "k8s.io/kubernetes/pkg/kubelet/metrics" -) - -type podScope struct { - scope -} - -// Ensure podScope implements Scope interface -var _ Scope = &podScope{} - -// NewPodScope returns a pod scope. -func NewPodScope(policy Policy) Scope { - return &podScope{ - scope{ - name: podTopologyScope, - podTopologyHints: podTopologyHints{}, - policy: policy, - podMap: containermap.NewContainerMap(), - }, - } -} - -func (s *podScope) Admit(pod *v1.Pod) lifecycle.PodAdmitResult { - bestHint, admit := s.calculateAffinity(pod) - klog.InfoS("Best TopologyHint", "bestHint", bestHint, "pod", klog.KObj(pod)) - if !admit { - if IsAlignmentGuaranteed(s.policy) { - // increment only if we know we allocate aligned resources. - metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopePod, metrics.AlignedNUMANode).Inc() - } - metrics.TopologyManagerAdmissionErrorsTotal.Inc() - return admission.GetPodAdmitResult(&TopologyAffinityError{}) - } - - for _, container := range append(pod.Spec.InitContainers, pod.Spec.Containers...) { - klog.InfoS("Topology Affinity", "bestHint", bestHint, "pod", klog.KObj(pod), "containerName", container.Name) - s.setTopologyHints(string(pod.UID), container.Name, bestHint) - - err := s.allocateAlignedResources(pod, &container) - if err != nil { - metrics.TopologyManagerAdmissionErrorsTotal.Inc() - return admission.GetPodAdmitResult(err) - } - } - if IsAlignmentGuaranteed(s.policy) { - // increment only if we know we allocate aligned resources. - klog.V(4).InfoS("Resource alignment at pod scope guaranteed", "pod", klog.KObj(pod)) - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopePod, metrics.AlignedNUMANode).Inc() - } - return admission.GetPodAdmitResult(nil) -} - -func (s *podScope) accumulateProvidersHints(pod *v1.Pod) []map[string][]TopologyHint { - var providersHints []map[string][]TopologyHint - - for _, provider := range s.hintProviders { - // Get the TopologyHints for a Pod from a provider. - hints := provider.GetPodTopologyHints(pod) - providersHints = append(providersHints, hints) - klog.InfoS("TopologyHints", "hints", hints, "pod", klog.KObj(pod)) - } - return providersHints -} - -func (s *podScope) calculateAffinity(pod *v1.Pod) (TopologyHint, bool) { - providersHints := s.accumulateProvidersHints(pod) - bestHint, admit := s.policy.Merge(providersHints) - klog.InfoS("PodTopologyHint", "bestHint", bestHint, "pod", klog.KObj(pod)) - return bestHint, admit -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go deleted file mode 100644 index ccaba099f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/topology_manager.go +++ /dev/null @@ -1,234 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package topologymanager - -import ( - "fmt" - "time" - - cadvisorapi "github.com/google/cadvisor/info/v1" - v1 "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask" - "k8s.io/kubernetes/pkg/kubelet/lifecycle" - "k8s.io/kubernetes/pkg/kubelet/metrics" -) - -const ( - // defaultMaxAllowableNUMANodes specifies the maximum number of NUMA Nodes that - // the TopologyManager supports on the underlying machine. - // - // At present, having more than this number of NUMA Nodes will result in a - // state explosion when trying to enumerate possible NUMAAffinity masks and - // generate hints for them. As such, if more NUMA Nodes than this are - // present on a machine and the TopologyManager is enabled, an error will - // be returned and the TopologyManager will not be loaded. - defaultMaxAllowableNUMANodes = 8 - // ErrorTopologyAffinity represents the type for a TopologyAffinityError - ErrorTopologyAffinity = "TopologyAffinityError" -) - -// TopologyAffinityError represents an resource alignment error -type TopologyAffinityError struct{} - -func (e TopologyAffinityError) Error() string { - return "Resources cannot be allocated with Topology locality" -} - -func (e TopologyAffinityError) Type() string { - return ErrorTopologyAffinity -} - -// Manager interface provides methods for Kubelet to manage pod topology hints -type Manager interface { - // PodAdmitHandler is implemented by Manager - lifecycle.PodAdmitHandler - // AddHintProvider adds a hint provider to manager to indicate the hint provider - // wants to be consulted with when making topology hints - AddHintProvider(HintProvider) - // AddContainer adds pod to Manager for tracking - AddContainer(pod *v1.Pod, container *v1.Container, containerID string) - // RemoveContainer removes pod from Manager tracking - RemoveContainer(containerID string) error - // Store is the interface for storing pod topology hints - Store -} - -type manager struct { - //Topology Manager Scope - scope Scope -} - -// HintProvider is an interface for components that want to collaborate to -// achieve globally optimal concrete resource alignment with respect to -// NUMA locality. -type HintProvider interface { - // GetTopologyHints returns a map of resource names to a list of possible - // concrete resource allocations in terms of NUMA locality hints. Each hint - // is optionally marked "preferred" and indicates the set of NUMA nodes - // involved in the hypothetical allocation. The topology manager calls - // this function for each hint provider, and merges the hints to produce - // a consensus "best" hint. The hint providers may subsequently query the - // topology manager to influence actual resource assignment. - GetTopologyHints(pod *v1.Pod, container *v1.Container) map[string][]TopologyHint - // GetPodTopologyHints returns a map of resource names to a list of possible - // concrete resource allocations per Pod in terms of NUMA locality hints. - GetPodTopologyHints(pod *v1.Pod) map[string][]TopologyHint - // Allocate triggers resource allocation to occur on the HintProvider after - // all hints have been gathered and the aggregated Hint is available via a - // call to Store.GetAffinity(). - Allocate(pod *v1.Pod, container *v1.Container) error -} - -// Store interface is to allow Hint Providers to retrieve pod affinity -type Store interface { - GetAffinity(podUID string, containerName string) TopologyHint - GetPolicy() Policy -} - -// TopologyHint is a struct containing the NUMANodeAffinity for a Container -type TopologyHint struct { - NUMANodeAffinity bitmask.BitMask - // Preferred is set to true when the NUMANodeAffinity encodes a preferred - // allocation for the Container. It is set to false otherwise. - Preferred bool -} - -// IsEqual checks if TopologyHint are equal -func (th *TopologyHint) IsEqual(topologyHint TopologyHint) bool { - if th.Preferred == topologyHint.Preferred { - if th.NUMANodeAffinity == nil || topologyHint.NUMANodeAffinity == nil { - return th.NUMANodeAffinity == topologyHint.NUMANodeAffinity - } - return th.NUMANodeAffinity.IsEqual(topologyHint.NUMANodeAffinity) - } - return false -} - -// LessThan checks if TopologyHint `a` is less than TopologyHint `b` -// this means that either `a` is a preferred hint and `b` is not -// or `a` NUMANodeAffinity attribute is narrower than `b` NUMANodeAffinity attribute. -func (th *TopologyHint) LessThan(other TopologyHint) bool { - if th.Preferred != other.Preferred { - return th.Preferred - } - return th.NUMANodeAffinity.IsNarrowerThan(other.NUMANodeAffinity) -} - -var _ Manager = &manager{} - -// NewManager creates a new TopologyManager based on provided policy and scope -func NewManager(topology []cadvisorapi.Node, topologyPolicyName string, topologyScopeName string, topologyPolicyOptions map[string]string) (Manager, error) { - // When policy is none, the scope is not relevant, so we can short circuit here. - if topologyPolicyName == PolicyNone { - klog.InfoS("Creating topology manager with none policy") - return &manager{scope: NewNoneScope()}, nil - } - - opts, err := NewPolicyOptions(topologyPolicyOptions) - if err != nil { - return nil, err - } - - klog.InfoS("Creating topology manager with policy per scope", "topologyPolicyName", topologyPolicyName, "topologyScopeName", topologyScopeName, "topologyPolicyOptions", opts) - - numaInfo, err := NewNUMAInfo(topology, opts) - if err != nil { - return nil, fmt.Errorf("cannot discover NUMA topology: %w", err) - } - - if topologyPolicyName != PolicyNone && len(numaInfo.Nodes) > opts.MaxAllowableNUMANodes { - return nil, fmt.Errorf("unsupported on machines with more than %v NUMA Nodes", opts.MaxAllowableNUMANodes) - } - - var policy Policy - switch topologyPolicyName { - - case PolicyBestEffort: - policy = NewBestEffortPolicy(numaInfo, opts) - - case PolicyRestricted: - policy = NewRestrictedPolicy(numaInfo, opts) - - case PolicySingleNumaNode: - policy = NewSingleNumaNodePolicy(numaInfo, opts) - - default: - return nil, fmt.Errorf("unknown policy: \"%s\"", topologyPolicyName) - } - - var scope Scope - switch topologyScopeName { - - case containerTopologyScope: - scope = NewContainerScope(policy) - - case podTopologyScope: - scope = NewPodScope(policy) - - default: - return nil, fmt.Errorf("unknown scope: \"%s\"", topologyScopeName) - } - - manager := &manager{ - scope: scope, - } - - manager.initializeMetrics() - - return manager, nil -} - -func (m *manager) initializeMetrics() { - // ensure the values exist - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedNUMANode).Add(0) - metrics.ContainerAlignedComputeResources.WithLabelValues(metrics.AlignScopePod, metrics.AlignedNUMANode).Add(0) - metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopeContainer, metrics.AlignedNUMANode).Add(0) - metrics.ContainerAlignedComputeResourcesFailure.WithLabelValues(metrics.AlignScopePod, metrics.AlignedNUMANode).Add(0) -} - -func (m *manager) GetAffinity(podUID string, containerName string) TopologyHint { - return m.scope.GetAffinity(podUID, containerName) -} - -func (m *manager) GetPolicy() Policy { - return m.scope.GetPolicy() -} - -func (m *manager) AddHintProvider(h HintProvider) { - m.scope.AddHintProvider(h) -} - -func (m *manager) AddContainer(pod *v1.Pod, container *v1.Container, containerID string) { - m.scope.AddContainer(pod, container, containerID) -} - -func (m *manager) RemoveContainer(containerID string) error { - return m.scope.RemoveContainer(containerID) -} - -func (m *manager) Admit(attrs *lifecycle.PodAdmitAttributes) lifecycle.PodAdmitResult { - klog.V(4).InfoS("Topology manager admission check", "pod", klog.KObj(attrs.Pod)) - metrics.TopologyManagerAdmissionRequestsTotal.Inc() - - startTime := time.Now() - podAdmitResult := m.scope.Admit(attrs.Pod) - metrics.TopologyManagerAdmissionDuration.Observe(float64(time.Since(startTime).Milliseconds())) - - klog.V(4).InfoS("Pod Admit Result", "Message", podAdmitResult.Message, "pod", klog.KObj(attrs.Pod)) - return podAdmitResult -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/types.go deleted file mode 100644 index e6338d3af..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/types.go +++ /dev/null @@ -1,140 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cm - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/utils/cpuset" -) - -// ResourceConfig holds information about all the supported cgroup resource parameters. -type ResourceConfig struct { - // Memory limit (in bytes). - Memory *int64 - // CPU set (number of CPUs the cgroup has access to). - CPUSet cpuset.CPUSet - // CPU shares (relative weight vs. other containers). - CPUShares *uint64 - // CPU hardcap limit (in usecs). Allowed cpu time in a given period. - CPUQuota *int64 - // CPU quota period. - CPUPeriod *uint64 - // HugePageLimit map from page size (in bytes) to limit (in bytes) - HugePageLimit map[int64]int64 - // Maximum number of pids - PidsLimit *int64 - // Unified for cgroup v2 - Unified map[string]string -} - -// CgroupName is the abstract name of a cgroup prior to any driver specific conversion. -// It is specified as a list of strings from its individual components, such as: -// {"kubepods", "burstable", "pod1234-abcd-5678-efgh"} -type CgroupName []string - -// CgroupConfig holds the cgroup configuration information. -// This is common object which is used to specify -// cgroup information to both systemd and raw cgroup fs -// implementation of the Cgroup Manager interface. -type CgroupConfig struct { - // Fully qualified name prior to any driver specific conversions. - Name CgroupName - // ResourceParameters contains various cgroups settings to apply. - ResourceParameters *ResourceConfig -} - -// CgroupManager allows for cgroup management. -// Supports Cgroup Creation ,Deletion and Updates. -type CgroupManager interface { - // Create creates and applies the cgroup configurations on the cgroup. - // It just creates the leaf cgroups. - // It expects the parent cgroup to already exist. - Create(*CgroupConfig) error - // Destroy the cgroup. - Destroy(*CgroupConfig) error - // Update cgroup configuration. - Update(*CgroupConfig) error - // Validate checks if the cgroup is valid - Validate(name CgroupName) error - // Exists checks if the cgroup already exists - Exists(name CgroupName) bool - // Name returns the literal cgroupfs name on the host after any driver specific conversions. - // We would expect systemd implementation to make appropriate name conversion. - // For example, if we pass {"foo", "bar"} - // then systemd should convert the name to something like - // foo.slice/foo-bar.slice - Name(name CgroupName) string - // CgroupName converts the literal cgroupfs name on the host to an internal identifier. - CgroupName(name string) CgroupName - // Pids scans through all subsystems to find pids associated with specified cgroup. - Pids(name CgroupName) []int - // ReduceCPULimits reduces the CPU CFS values to the minimum amount of shares. - ReduceCPULimits(cgroupName CgroupName) error - // MemoryUsage returns current memory usage of the specified cgroup, as read from the cgroupfs. - MemoryUsage(name CgroupName) (int64, error) - // Get the resource config values applied to the cgroup for specified resource type - GetCgroupConfig(name CgroupName, resource v1.ResourceName) (*ResourceConfig, error) - // Set resource config for the specified resource type on the cgroup - SetCgroupConfig(name CgroupName, resourceConfig *ResourceConfig) error - // Version of the cgroup implementation on the host - Version() int -} - -// QOSContainersInfo stores the names of containers per qos -type QOSContainersInfo struct { - Guaranteed CgroupName - BestEffort CgroupName - Burstable CgroupName -} - -// PodContainerManager stores and manages pod level containers -// The Pod workers interact with the PodContainerManager to create and destroy -// containers for the pod. -type PodContainerManager interface { - // GetPodContainerName returns the CgroupName identifier, and its literal cgroupfs form on the host. - GetPodContainerName(*v1.Pod) (CgroupName, string) - - // EnsureExists takes a pod as argument and makes sure that - // pod cgroup exists if qos cgroup hierarchy flag is enabled. - // If the pod cgroup doesn't already exist this method creates it. - EnsureExists(*v1.Pod) error - - // Exists returns true if the pod cgroup exists. - Exists(*v1.Pod) bool - - // Destroy takes a pod Cgroup name as argument and destroys the pod's container. - Destroy(name CgroupName) error - - // ReduceCPULimits reduces the CPU CFS values to the minimum amount of shares. - ReduceCPULimits(name CgroupName) error - - // GetAllPodsFromCgroups enumerates the set of pod uids to their associated cgroup based on state of cgroupfs system. - GetAllPodsFromCgroups() (map[types.UID]CgroupName, error) - - // IsPodCgroup returns true if the literal cgroupfs name corresponds to a pod - IsPodCgroup(cgroupfs string) (bool, types.UID) - - // Get value of memory usage for the pod Cgroup - GetPodCgroupMemoryUsage(pod *v1.Pod) (uint64, error) - - // Get the resource config values applied to the pod cgroup for specified resource type - GetPodCgroupConfig(pod *v1.Pod, resource v1.ResourceName) (*ResourceConfig, error) - - // Set resource config values for the specified resource type on the pod cgroup - SetPodCgroupConfig(pod *v1.Pod, resourceConfig *ResourceConfig) error -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_linux.go deleted file mode 100644 index c63c0b410..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_linux.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "path/filepath" - - libcontainerutils "k8s.io/kubernetes/third_party/forked/libcontainer/utils" - - libcontainercgroups "github.com/opencontainers/cgroups" -) - -const ( - // CgroupRoot is the base path where cgroups are mounted - CgroupRoot = "/sys/fs/cgroup" -) - -// GetPids gets pids of the desired cgroup -// Forked from opencontainers/runc/libcontainer/cgroup/fs.Manager.GetPids() -func GetPids(cgroupPath string) ([]int, error) { - dir := "" - - if libcontainercgroups.IsCgroup2UnifiedMode() { - path, err := filepath.Rel("/", cgroupPath) - if err != nil { - return nil, err - } - dir = filepath.Join(CgroupRoot, path) - } else { - var err error - dir, err = getCgroupV1Path(cgroupPath) - if err != nil { - return nil, err - } - } - return libcontainercgroups.GetPids(dir) -} - -// getCgroupV1Path gets the file path to the "devices" subsystem of the desired cgroup. -// cgroupPath is the path in the cgroup hierarchy. -func getCgroupV1Path(cgroupPath string) (string, error) { - cgroupPath = libcontainerutils.CleanPath(cgroupPath) - - mnt, root, err := libcontainercgroups.FindCgroupMountpointAndRoot(cgroupPath, "devices") - // If we didn't mount the subsystem, there is no point we make the path. - if err != nil { - return "", err - } - - // If the cgroup name/path is absolute do not look relative to the cgroup of the init process. - if filepath.IsAbs(cgroupPath) { - // Sometimes subsystems can be mounted together as 'cpu,cpuacct'. - return filepath.Join(root, mnt, cgroupPath), nil - } - - parentPath, err := getCgroupV1ParentPath(mnt, root) - if err != nil { - return "", err - } - - return filepath.Join(parentPath, cgroupPath), nil -} - -// getCgroupV1ParentPath gets the parent filepath to this cgroup, for resolving relative cgroup paths. -func getCgroupV1ParentPath(mountpoint, root string) (string, error) { - // Use GetThisCgroupDir instead of GetInitCgroupDir, because the creating - // process could in container and shared pid namespace with host, and - // /proc/1/cgroup could point to whole other world of cgroups. - initPath, err := libcontainercgroups.GetOwnCgroup("devices") - if err != nil { - return "", err - } - // This is needed for nested containers, because in /proc/self/cgroup we - // see paths from host, which don't exist in container. - relDir, err := filepath.Rel(root, initPath) - if err != nil { - return "", err - } - return filepath.Join(mountpoint, relDir), nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go deleted file mode 100644 index b655f4138..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/cm/util/cgroups_unsupported.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build !linux -// +build !linux - -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -// GetPids gets pids of the desired cgroup -func GetPids(cgroupPath string) ([]int, error) { - return nil, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go deleted file mode 100644 index b67f6c34f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/apiserver.go +++ /dev/null @@ -1,68 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "time" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/fields" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" - clientset "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/cache" - "k8s.io/klog/v2" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" -) - -// WaitForAPIServerSyncPeriod is the period between checks for the node list/watch initial sync -const WaitForAPIServerSyncPeriod = 1 * time.Second - -// NewSourceApiserver creates a config source that watches and pulls from the apiserver. -func NewSourceApiserver(c clientset.Interface, nodeName types.NodeName, nodeHasSynced func() bool, updates chan<- interface{}) { - lw := cache.NewListWatchFromClient(c.CoreV1().RESTClient(), "pods", metav1.NamespaceAll, fields.OneTermEqualSelector("spec.nodeName", string(nodeName))) - - // The Reflector responsible for watching pods at the apiserver should be run only after - // the node sync with the apiserver has completed. - klog.InfoS("Waiting for node sync before watching apiserver pods") - go func() { - for { - if nodeHasSynced() { - klog.V(4).InfoS("node sync completed") - break - } - time.Sleep(WaitForAPIServerSyncPeriod) - klog.V(4).InfoS("node sync has not completed yet") - } - klog.InfoS("Watching apiserver") - newSourceApiserverFromLW(lw, updates) - }() -} - -// newSourceApiserverFromLW holds creates a config source that watches and pulls from the apiserver. -func newSourceApiserverFromLW(lw cache.ListerWatcher, updates chan<- interface{}) { - send := func(objs []interface{}) { - var pods []*v1.Pod - for _, o := range objs { - pods = append(pods, o.(*v1.Pod)) - } - updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.ApiserverSource} - } - r := cache.NewReflector(lw, &v1.Pod{}, cache.NewUndeltaStore(send, cache.MetaNamespaceKeyFunc), 0) - go r.Run(wait.NeverStop) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/common.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/common.go deleted file mode 100644 index a73d6372a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/common.go +++ /dev/null @@ -1,197 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "crypto/md5" - "encoding/hex" - "errors" - "fmt" - "strings" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - utilyaml "k8s.io/apimachinery/pkg/util/yaml" - api "k8s.io/kubernetes/pkg/apis/core" - "k8s.io/kubernetes/pkg/apis/core/helper" - - // TODO: remove this import if - // api.Registry.GroupOrDie(v1.GroupName).GroupVersion.String() is changed - // to "v1"? - "k8s.io/kubernetes/pkg/api/legacyscheme" - // Ensure that core apis are installed - _ "k8s.io/kubernetes/pkg/apis/core/install" - k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" - "k8s.io/kubernetes/pkg/apis/core/validation" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" - "k8s.io/kubernetes/pkg/util/hash" - - "k8s.io/klog/v2" -) - -const ( - maxConfigLength = 10 * 1 << 20 // 10MB -) - -// Generate a pod name that is unique among nodes by appending the nodeName. -func generatePodName(name string, nodeName types.NodeName) string { - return fmt.Sprintf("%s-%s", name, strings.ToLower(string(nodeName))) -} - -func applyDefaults(pod *api.Pod, source string, isFile bool, nodeName types.NodeName) error { - if len(pod.UID) == 0 { - hasher := md5.New() - hash.DeepHashObject(hasher, pod) - // DeepHashObject resets the hash, so we should write the pod source - // information AFTER it. - if isFile { - fmt.Fprintf(hasher, "host:%s", nodeName) - fmt.Fprintf(hasher, "file:%s", source) - } else { - fmt.Fprintf(hasher, "url:%s", source) - } - pod.UID = types.UID(hex.EncodeToString(hasher.Sum(nil)[0:])) - klog.V(5).InfoS("Generated UID", "pod", klog.KObj(pod), "podUID", pod.UID, "source", source) - } - - pod.Name = generatePodName(pod.Name, nodeName) - klog.V(5).InfoS("Generated pod name", "pod", klog.KObj(pod), "podUID", pod.UID, "source", source) - - if pod.Namespace == "" { - pod.Namespace = metav1.NamespaceDefault - } - klog.V(5).InfoS("Set namespace for pod", "pod", klog.KObj(pod), "source", source) - - // Set the Host field to indicate this pod is scheduled on the current node. - pod.Spec.NodeName = string(nodeName) - - if pod.Annotations == nil { - pod.Annotations = make(map[string]string) - } - // The generated UID is the hash of the file. - pod.Annotations[kubetypes.ConfigHashAnnotationKey] = string(pod.UID) - - if isFile { - // Applying the default Taint tolerations to static pods, - // so they are not evicted when there are node problems. - helper.AddOrUpdateTolerationInPod(pod, &api.Toleration{ - Operator: "Exists", - Effect: api.TaintEffectNoExecute, - }) - } - - // Set the default status to pending. - pod.Status.Phase = api.PodPending - return nil -} - -type defaultFunc func(pod *api.Pod) error - -// A static pod tried to use a ClusterTrustBundle projected volume source. -var ErrStaticPodTriedToUseClusterTrustBundle = errors.New("static pods may not use ClusterTrustBundle projected volume sources") - -// A static pod tried to use a resource claim. -var ErrStaticPodTriedToUseResourceClaims = errors.New("static pods may not use ResourceClaims") - -// tryDecodeSinglePod takes data and tries to extract valid Pod config information from it. -func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v1.Pod, err error) { - // JSON is valid YAML, so this should work for everything. - json, err := utilyaml.ToJSON(data) - if err != nil { - return false, nil, err - } - obj, err := runtime.Decode(legacyscheme.Codecs.UniversalDecoder(), json) - if err != nil { - return false, pod, err - } - - newPod, ok := obj.(*api.Pod) - // Check whether the object could be converted to single pod. - if !ok { - return false, pod, fmt.Errorf("invalid pod: %#v", obj) - } - - if newPod.Name == "" { - return true, pod, fmt.Errorf("invalid pod: name is needed for the pod") - } - - // Apply default values and validate the pod. - if err = defaultFn(newPod); err != nil { - return true, pod, err - } - if errs := validation.ValidatePodCreate(newPod, validation.PodValidationOptions{}); len(errs) > 0 { - return true, pod, fmt.Errorf("invalid pod: %v", errs) - } - v1Pod := &v1.Pod{} - if err := k8s_api_v1.Convert_core_Pod_To_v1_Pod(newPod, v1Pod, nil); err != nil { - klog.ErrorS(err, "Pod failed to convert to v1", "pod", klog.KObj(newPod)) - return true, nil, err - } - - for _, v := range v1Pod.Spec.Volumes { - if v.Projected == nil { - continue - } - - for _, s := range v.Projected.Sources { - if s.ClusterTrustBundle != nil { - return true, nil, ErrStaticPodTriedToUseClusterTrustBundle - } - } - } - if len(v1Pod.Spec.ResourceClaims) > 0 { - return true, nil, ErrStaticPodTriedToUseResourceClaims - } - - return true, v1Pod, nil -} - -func tryDecodePodList(data []byte, defaultFn defaultFunc) (parsed bool, pods v1.PodList, err error) { - obj, err := runtime.Decode(legacyscheme.Codecs.UniversalDecoder(), data) - if err != nil { - return false, pods, err - } - - newPods, ok := obj.(*api.PodList) - // Check whether the object could be converted to list of pods. - if !ok { - err = fmt.Errorf("invalid pods list: %#v", obj) - return false, pods, err - } - - // Apply default values and validate pods. - for i := range newPods.Items { - newPod := &newPods.Items[i] - if newPod.Name == "" { - return true, pods, fmt.Errorf("invalid pod: name is needed for the pod") - } - if err = defaultFn(newPod); err != nil { - return true, pods, err - } - if errs := validation.ValidatePodCreate(newPod, validation.PodValidationOptions{}); len(errs) > 0 { - err = fmt.Errorf("invalid pod: %v", errs) - return true, pods, err - } - } - v1Pods := &v1.PodList{} - if err := k8s_api_v1.Convert_core_PodList_To_v1_PodList(newPods, v1Pods, nil); err != nil { - return true, pods, err - } - return true, *v1Pods, err -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go deleted file mode 100644 index 10a42c823..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/config.go +++ /dev/null @@ -1,500 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "context" - "fmt" - "reflect" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/tools/record" - "k8s.io/klog/v2" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/events" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" - "k8s.io/kubernetes/pkg/kubelet/util/format" -) - -// PodConfigNotificationMode describes how changes are sent to the update channel. -type PodConfigNotificationMode int - -const ( - // PodConfigNotificationUnknown is the default value for - // PodConfigNotificationMode when uninitialized. - PodConfigNotificationUnknown PodConfigNotificationMode = iota - // PodConfigNotificationSnapshot delivers the full configuration as a SET whenever - // any change occurs. - PodConfigNotificationSnapshot - // PodConfigNotificationSnapshotAndUpdates delivers an UPDATE and DELETE message whenever pods are - // changed, and a SET message if there are any additions or removals. - PodConfigNotificationSnapshotAndUpdates - // PodConfigNotificationIncremental delivers ADD, UPDATE, DELETE, REMOVE, RECONCILE to the update channel. - PodConfigNotificationIncremental -) - -type podStartupSLIObserver interface { - ObservedPodOnWatch(pod *v1.Pod, when time.Time) -} - -// PodConfig is a configuration mux that merges many sources of pod configuration into a single -// consistent structure, and then delivers incremental change notifications to listeners -// in order. -type PodConfig struct { - pods *podStorage - mux *mux - - // the channel of denormalized changes passed to listeners - updates chan kubetypes.PodUpdate - - // contains the list of all configured sources - sourcesLock sync.Mutex - sources sets.Set[string] -} - -// NewPodConfig creates an object that can merge many configuration sources into a stream -// of normalized updates to a pod configuration. -func NewPodConfig(mode PodConfigNotificationMode, recorder record.EventRecorder, startupSLIObserver podStartupSLIObserver) *PodConfig { - updates := make(chan kubetypes.PodUpdate, 50) - storage := newPodStorage(updates, mode, recorder, startupSLIObserver) - podConfig := &PodConfig{ - pods: storage, - mux: newMux(storage), - updates: updates, - sources: sets.Set[string]{}, - } - return podConfig -} - -// Channel creates or returns a config source channel. The channel -// only accepts PodUpdates -func (c *PodConfig) Channel(ctx context.Context, source string) chan<- interface{} { - c.sourcesLock.Lock() - defer c.sourcesLock.Unlock() - c.sources.Insert(source) - return c.mux.ChannelWithContext(ctx, source) -} - -// SeenAllSources returns true if seenSources contains all sources in the -// config, and also this config has received a SET message from each source. -func (c *PodConfig) SeenAllSources(seenSources sets.Set[string]) bool { - if c.pods == nil { - return false - } - c.sourcesLock.Lock() - defer c.sourcesLock.Unlock() - klog.V(5).InfoS("Looking for sources, have seen", "sources", sets.List(c.sources), "seenSources", seenSources) - return seenSources.HasAll(sets.List(c.sources)...) && c.pods.seenSources(sets.List(c.sources)...) -} - -// Updates returns a channel of updates to the configuration, properly denormalized. -func (c *PodConfig) Updates() <-chan kubetypes.PodUpdate { - return c.updates -} - -// Sync requests the full configuration be delivered to the update channel. -func (c *PodConfig) Sync() { - c.pods.sync() -} - -// podStorage manages the current pod state at any point in time and ensures updates -// to the channel are delivered in order. Note that this object is an in-memory source of -// "truth" and on creation contains zero entries. Once all previously read sources are -// available, then this object should be considered authoritative. -type podStorage struct { - podLock sync.RWMutex - // map of source name to pod uid to pod reference - pods map[string]map[types.UID]*v1.Pod - mode PodConfigNotificationMode - - // ensures that updates are delivered in strict order - // on the updates channel - updateLock sync.Mutex - updates chan<- kubetypes.PodUpdate - - // contains the set of all sources that have sent at least one SET - sourcesSeenLock sync.RWMutex - sourcesSeen sets.Set[string] - - // the EventRecorder to use - recorder record.EventRecorder - - startupSLIObserver podStartupSLIObserver -} - -// TODO: PodConfigNotificationMode could be handled by a listener to the updates channel -// in the future, especially with multiple listeners. -// TODO: allow initialization of the current state of the store with snapshotted version. -func newPodStorage(updates chan<- kubetypes.PodUpdate, mode PodConfigNotificationMode, recorder record.EventRecorder, startupSLIObserver podStartupSLIObserver) *podStorage { - return &podStorage{ - pods: make(map[string]map[types.UID]*v1.Pod), - mode: mode, - updates: updates, - sourcesSeen: sets.Set[string]{}, - recorder: recorder, - startupSLIObserver: startupSLIObserver, - } -} - -// Merge normalizes a set of incoming changes from different sources into a map of all Pods -// and ensures that redundant changes are filtered out, and then pushes zero or more minimal -// updates onto the update channel. Ensures that updates are delivered in order. -func (s *podStorage) Merge(source string, change interface{}) error { - s.updateLock.Lock() - defer s.updateLock.Unlock() - - seenBefore := s.sourcesSeen.Has(source) - adds, updates, deletes, removes, reconciles := s.merge(source, change) - firstSet := !seenBefore && s.sourcesSeen.Has(source) - - // deliver update notifications - switch s.mode { - case PodConfigNotificationIncremental: - if len(removes.Pods) > 0 { - s.updates <- *removes - } - if len(adds.Pods) > 0 { - s.updates <- *adds - } - if len(updates.Pods) > 0 { - s.updates <- *updates - } - if len(deletes.Pods) > 0 { - s.updates <- *deletes - } - if firstSet && len(adds.Pods) == 0 && len(updates.Pods) == 0 && len(deletes.Pods) == 0 { - // Send an empty update when first seeing the source and there are - // no ADD or UPDATE or DELETE pods from the source. This signals kubelet that - // the source is ready. - s.updates <- *adds - } - // Only add reconcile support here, because kubelet doesn't support Snapshot update now. - if len(reconciles.Pods) > 0 { - s.updates <- *reconciles - } - - case PodConfigNotificationSnapshotAndUpdates: - if len(removes.Pods) > 0 || len(adds.Pods) > 0 || firstSet { - s.updates <- kubetypes.PodUpdate{Pods: s.mergedState().([]*v1.Pod), Op: kubetypes.SET, Source: source} - } - if len(updates.Pods) > 0 { - s.updates <- *updates - } - if len(deletes.Pods) > 0 { - s.updates <- *deletes - } - - case PodConfigNotificationSnapshot: - if len(updates.Pods) > 0 || len(deletes.Pods) > 0 || len(adds.Pods) > 0 || len(removes.Pods) > 0 || firstSet { - s.updates <- kubetypes.PodUpdate{Pods: s.mergedState().([]*v1.Pod), Op: kubetypes.SET, Source: source} - } - - case PodConfigNotificationUnknown: - fallthrough - default: - panic(fmt.Sprintf("unsupported PodConfigNotificationMode: %#v", s.mode)) - } - - return nil -} - -func (s *podStorage) merge(source string, change interface{}) (adds, updates, deletes, removes, reconciles *kubetypes.PodUpdate) { - s.podLock.Lock() - defer s.podLock.Unlock() - - addPods := []*v1.Pod{} - updatePods := []*v1.Pod{} - deletePods := []*v1.Pod{} - removePods := []*v1.Pod{} - reconcilePods := []*v1.Pod{} - - pods := s.pods[source] - if pods == nil { - pods = make(map[types.UID]*v1.Pod) - } - - // updatePodFunc is the local function which updates the pod cache *oldPods* with new pods *newPods*. - // After updated, new pod will be stored in the pod cache *pods*. - // Notice that *pods* and *oldPods* could be the same cache. - updatePodsFunc := func(newPods []*v1.Pod, oldPods, pods map[types.UID]*v1.Pod) { - filtered := filterInvalidPods(newPods, source, s.recorder) - for _, ref := range filtered { - // Annotate the pod with the source before any comparison. - if ref.Annotations == nil { - ref.Annotations = make(map[string]string) - } - ref.Annotations[kubetypes.ConfigSourceAnnotationKey] = source - // ignore static pods - if !kubetypes.IsStaticPod(ref) { - s.startupSLIObserver.ObservedPodOnWatch(ref, time.Now()) - } - if existing, found := oldPods[ref.UID]; found { - pods[ref.UID] = existing - needUpdate, needReconcile, needGracefulDelete := checkAndUpdatePod(existing, ref) - if needUpdate { - updatePods = append(updatePods, existing) - } else if needReconcile { - reconcilePods = append(reconcilePods, existing) - } else if needGracefulDelete { - deletePods = append(deletePods, existing) - } - continue - } - recordFirstSeenTime(ref) - pods[ref.UID] = ref - addPods = append(addPods, ref) - } - } - - update := change.(kubetypes.PodUpdate) - switch update.Op { - case kubetypes.ADD, kubetypes.UPDATE, kubetypes.DELETE: - if update.Op == kubetypes.ADD { - klog.V(4).InfoS("Adding new pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - } else if update.Op == kubetypes.DELETE { - klog.V(4).InfoS("Gracefully deleting pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - } else { - klog.V(4).InfoS("Updating pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - } - updatePodsFunc(update.Pods, pods, pods) - - case kubetypes.REMOVE: - klog.V(4).InfoS("Removing pods from source", "source", source, "pods", klog.KObjSlice(update.Pods)) - for _, value := range update.Pods { - if existing, found := pods[value.UID]; found { - // this is a delete - delete(pods, value.UID) - removePods = append(removePods, existing) - continue - } - // this is a no-op - } - - case kubetypes.SET: - klog.V(4).InfoS("Setting pods for source", "source", source) - s.markSourceSet(source) - // Clear the old map entries by just creating a new map - oldPods := pods - pods = make(map[types.UID]*v1.Pod) - updatePodsFunc(update.Pods, oldPods, pods) - for uid, existing := range oldPods { - if _, found := pods[uid]; !found { - // this is a delete - removePods = append(removePods, existing) - } - } - - default: - klog.InfoS("Received invalid update type", "type", update) - - } - - s.pods[source] = pods - - adds = &kubetypes.PodUpdate{Op: kubetypes.ADD, Pods: copyPods(addPods), Source: source} - updates = &kubetypes.PodUpdate{Op: kubetypes.UPDATE, Pods: copyPods(updatePods), Source: source} - deletes = &kubetypes.PodUpdate{Op: kubetypes.DELETE, Pods: copyPods(deletePods), Source: source} - removes = &kubetypes.PodUpdate{Op: kubetypes.REMOVE, Pods: copyPods(removePods), Source: source} - reconciles = &kubetypes.PodUpdate{Op: kubetypes.RECONCILE, Pods: copyPods(reconcilePods), Source: source} - - return adds, updates, deletes, removes, reconciles -} - -func (s *podStorage) markSourceSet(source string) { - s.sourcesSeenLock.Lock() - defer s.sourcesSeenLock.Unlock() - s.sourcesSeen.Insert(source) -} - -func (s *podStorage) seenSources(sources ...string) bool { - s.sourcesSeenLock.RLock() - defer s.sourcesSeenLock.RUnlock() - return s.sourcesSeen.HasAll(sources...) -} - -func filterInvalidPods(pods []*v1.Pod, source string, recorder record.EventRecorder) (filtered []*v1.Pod) { - names := sets.Set[string]{} - for i, pod := range pods { - // Pods from each source are assumed to have passed validation individually. - // This function only checks if there is any naming conflict. - name := kubecontainer.GetPodFullName(pod) - if names.Has(name) { - klog.InfoS("Pod failed validation due to duplicate pod name, ignoring", "index", i, "pod", klog.KObj(pod), "source", source) - recorder.Eventf(pod, v1.EventTypeWarning, events.FailedValidation, "Error validating pod %s from %s due to duplicate pod name %q, ignoring", format.Pod(pod), source, pod.Name) - continue - } else { - names.Insert(name) - } - - filtered = append(filtered, pod) - } - return -} - -// Annotations that the kubelet adds to the pod. -var localAnnotations = []string{ - kubetypes.ConfigSourceAnnotationKey, - kubetypes.ConfigMirrorAnnotationKey, - kubetypes.ConfigFirstSeenAnnotationKey, -} - -func isLocalAnnotationKey(key string) bool { - for _, localKey := range localAnnotations { - if key == localKey { - return true - } - } - return false -} - -// isAnnotationMapEqual returns true if the existing annotation Map is equal to candidate except -// for local annotations. -func isAnnotationMapEqual(existingMap, candidateMap map[string]string) bool { - if candidateMap == nil { - candidateMap = make(map[string]string) - } - for k, v := range candidateMap { - if isLocalAnnotationKey(k) { - continue - } - if existingValue, ok := existingMap[k]; ok && existingValue == v { - continue - } - return false - } - for k := range existingMap { - if isLocalAnnotationKey(k) { - continue - } - // stale entry in existing map. - if _, exists := candidateMap[k]; !exists { - return false - } - } - return true -} - -// recordFirstSeenTime records the first seen time of this pod. -func recordFirstSeenTime(pod *v1.Pod) { - klog.V(4).InfoS("Receiving a new pod", "pod", klog.KObj(pod)) - pod.Annotations[kubetypes.ConfigFirstSeenAnnotationKey] = kubetypes.NewTimestamp().GetString() -} - -// updateAnnotations returns an Annotation map containing the api annotation map plus -// locally managed annotations -func updateAnnotations(existing, ref *v1.Pod) { - annotations := make(map[string]string, len(ref.Annotations)+len(localAnnotations)) - for k, v := range ref.Annotations { - annotations[k] = v - } - for _, k := range localAnnotations { - if v, ok := existing.Annotations[k]; ok { - annotations[k] = v - } - } - existing.Annotations = annotations -} - -func podsDifferSemantically(existing, ref *v1.Pod) bool { - if reflect.DeepEqual(existing.Spec, ref.Spec) && - reflect.DeepEqual(existing.Labels, ref.Labels) && - reflect.DeepEqual(existing.DeletionTimestamp, ref.DeletionTimestamp) && - reflect.DeepEqual(existing.DeletionGracePeriodSeconds, ref.DeletionGracePeriodSeconds) && - isAnnotationMapEqual(existing.Annotations, ref.Annotations) { - return false - } - return true -} - -// checkAndUpdatePod updates existing, and: -// - if ref makes a meaningful change, returns needUpdate=true -// - if ref makes a meaningful change, and this change is graceful deletion, returns needGracefulDelete=true -// - if ref makes no meaningful change, but changes the pod status, returns needReconcile=true -// - else return all false -// Now, needUpdate, needGracefulDelete and needReconcile should never be both true -func checkAndUpdatePod(existing, ref *v1.Pod) (needUpdate, needReconcile, needGracefulDelete bool) { - - // 1. this is a reconcile - // TODO: it would be better to update the whole object and only preserve certain things - // like the source annotation or the UID (to ensure safety) - if !podsDifferSemantically(existing, ref) { - // this is not an update - // Only check reconcile when it is not an update, because if the pod is going to - // be updated, an extra reconcile is unnecessary - if !reflect.DeepEqual(existing.Status, ref.Status) { - // Pod with changed pod status needs reconcile, because kubelet should - // be the source of truth of pod status. - existing.Status = ref.Status - needReconcile = true - } - return - } - - // Overwrite the first-seen time with the existing one. This is our own - // internal annotation, there is no need to update. - ref.Annotations[kubetypes.ConfigFirstSeenAnnotationKey] = existing.Annotations[kubetypes.ConfigFirstSeenAnnotationKey] - - existing.Spec = ref.Spec - existing.Labels = ref.Labels - existing.DeletionTimestamp = ref.DeletionTimestamp - existing.DeletionGracePeriodSeconds = ref.DeletionGracePeriodSeconds - existing.Generation = ref.Generation - existing.Status = ref.Status - updateAnnotations(existing, ref) - - // 2. this is an graceful delete - if ref.DeletionTimestamp != nil { - needGracefulDelete = true - } else { - // 3. this is an update - needUpdate = true - } - - return -} - -// sync sends a copy of the current state through the update channel. -func (s *podStorage) sync() { - s.updateLock.Lock() - defer s.updateLock.Unlock() - s.updates <- kubetypes.PodUpdate{Pods: s.mergedState().([]*v1.Pod), Op: kubetypes.SET, Source: kubetypes.AllSource} -} - -func (s *podStorage) mergedState() interface{} { - s.podLock.RLock() - defer s.podLock.RUnlock() - pods := make([]*v1.Pod, 0) - for _, sourcePods := range s.pods { - for _, podRef := range sourcePods { - pods = append(pods, podRef.DeepCopy()) - } - } - return pods -} - -func copyPods(sourcePods []*v1.Pod) []*v1.Pod { - pods := []*v1.Pod{} - for _, source := range sourcePods { - // Use a deep copy here just in case - pods = append(pods, source.DeepCopy()) - } - return pods -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/defaults.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/defaults.go deleted file mode 100644 index b8788f9e4..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/defaults.go +++ /dev/null @@ -1,34 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -// Defines sane defaults for the kubelet config. -const ( - DefaultKubeletPodsDirName = "pods" - DefaultKubeletVolumesDirName = "volumes" - DefaultKubeletVolumeSubpathsDirName = "volume-subpaths" - DefaultKubeletVolumeDevicesDirName = "volumeDevices" - DefaultKubeletPluginsDirName = "plugins" - DefaultKubeletPluginsRegistrationDirName = "plugins_registry" - DefaultKubeletContainersDirName = "containers" - DefaultKubeletPluginContainersDirName = "plugin-containers" - DefaultKubeletPodResourcesDirName = "pod-resources" - KubeletPluginsDirSELinuxLabel = "system_u:object_r:container_file_t:s0" - KubeletContainersSharedSELinuxLabel = "system_u:object_r:container_file_t:s0" - DefaultKubeletCheckpointsDirName = "checkpoints" - DefaultKubeletUserNamespacesIDsPerPod = 65536 -) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/doc.go deleted file mode 100644 index 1d839ba32..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package config implements the pod configuration readers. -package config diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go deleted file mode 100644 index 79e2af6ed..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file.go +++ /dev/null @@ -1,245 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "fmt" - "os" - "path/filepath" - "sort" - "strings" - "time" - - "k8s.io/klog/v2" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/cache" - api "k8s.io/kubernetes/pkg/apis/core" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" - utilio "k8s.io/utils/io" -) - -type podEventType int - -const ( - podAdd podEventType = iota - podModify - podDelete - - eventBufferLen = 10 -) - -type watchEvent struct { - fileName string - eventType podEventType -} - -type sourceFile struct { - path string - nodeName types.NodeName - period time.Duration - store cache.Store - fileKeyMapping map[string]string - updates chan<- interface{} - watchEvents chan *watchEvent -} - -// NewSourceFile watches a config file for changes. -func NewSourceFile(path string, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) { - // "github.com/sigma/go-inotify" requires a path without trailing "/" - path = strings.TrimRight(path, string(os.PathSeparator)) - - config := newSourceFile(path, nodeName, period, updates) - klog.V(1).InfoS("Watching path", "path", path) - config.run() -} - -func newSourceFile(path string, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) *sourceFile { - send := func(objs []interface{}) { - var pods []*v1.Pod - for _, o := range objs { - pods = append(pods, o.(*v1.Pod)) - } - updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.FileSource} - } - store := cache.NewUndeltaStore(send, cache.MetaNamespaceKeyFunc) - return &sourceFile{ - path: path, - nodeName: nodeName, - period: period, - store: store, - fileKeyMapping: map[string]string{}, - updates: updates, - watchEvents: make(chan *watchEvent, eventBufferLen), - } -} - -func (s *sourceFile) run() { - listTicker := time.NewTicker(s.period) - - go func() { - // Read path immediately to speed up startup. - if err := s.listConfig(); err != nil { - klog.ErrorS(err, "Unable to read config path", "path", s.path) - } - for { - select { - case <-listTicker.C: - if err := s.listConfig(); err != nil { - klog.ErrorS(err, "Unable to read config path", "path", s.path) - } - case e := <-s.watchEvents: - if err := s.consumeWatchEvent(e); err != nil { - klog.ErrorS(err, "Unable to process watch event") - } - } - } - }() - - s.startWatch() -} - -func (s *sourceFile) applyDefaults(pod *api.Pod, source string) error { - return applyDefaults(pod, source, true, s.nodeName) -} - -func (s *sourceFile) listConfig() error { - path := s.path - statInfo, err := os.Stat(path) - if err != nil { - if !os.IsNotExist(err) { - return err - } - // Emit an update with an empty PodList to allow FileSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{}, Op: kubetypes.SET, Source: kubetypes.FileSource} - return fmt.Errorf("path does not exist, ignoring") - } - - switch { - case statInfo.Mode().IsDir(): - pods, err := s.extractFromDir(path) - if err != nil { - return err - } - if len(pods) == 0 { - // Emit an update with an empty PodList to allow FileSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.FileSource} - return nil - } - return s.replaceStore(pods...) - - case statInfo.Mode().IsRegular(): - pod, err := s.extractFromFile(path) - if err != nil { - return err - } - return s.replaceStore(pod) - - default: - return fmt.Errorf("path is not a directory or file") - } -} - -// Get as many pod manifests as we can from a directory. Return an error if and only if something -// prevented us from reading anything at all. Do not return an error if only some files -// were problematic. -func (s *sourceFile) extractFromDir(name string) ([]*v1.Pod, error) { - dirents, err := filepath.Glob(filepath.Join(name, "[^.]*")) - if err != nil { - return nil, fmt.Errorf("glob failed: %v", err) - } - - pods := make([]*v1.Pod, 0, len(dirents)) - if len(dirents) == 0 { - return pods, nil - } - - sort.Strings(dirents) - for _, path := range dirents { - statInfo, err := os.Stat(path) - if err != nil { - klog.ErrorS(err, "Could not get metadata", "path", path) - continue - } - - switch { - case statInfo.Mode().IsDir(): - klog.ErrorS(nil, "Provided manifest path is a directory, not recursing into manifest path", "path", path) - case statInfo.Mode().IsRegular(): - pod, err := s.extractFromFile(path) - if err != nil { - if !os.IsNotExist(err) { - klog.ErrorS(err, "Could not process manifest file", "path", path) - } - } else { - pods = append(pods, pod) - } - default: - klog.ErrorS(nil, "Manifest path is not a directory or file", "path", path, "mode", statInfo.Mode()) - } - } - return pods, nil -} - -// extractFromFile parses a file for Pod configuration information. -func (s *sourceFile) extractFromFile(filename string) (pod *v1.Pod, err error) { - klog.V(3).InfoS("Reading config file", "path", filename) - defer func() { - if err == nil && pod != nil { - objKey, keyErr := cache.MetaNamespaceKeyFunc(pod) - if keyErr != nil { - err = keyErr - return - } - s.fileKeyMapping[filename] = objKey - } - }() - - file, err := os.Open(filename) - if err != nil { - return pod, err - } - defer file.Close() - - data, err := utilio.ReadAtMost(file, maxConfigLength) - if err != nil { - return pod, err - } - - defaultFn := func(pod *api.Pod) error { - return s.applyDefaults(pod, filename) - } - - parsed, pod, podErr := tryDecodeSinglePod(data, defaultFn) - if parsed { - if podErr != nil { - return pod, podErr - } - return pod, nil - } - - return pod, fmt.Errorf("%v: couldn't parse as pod(%v), please check config file", filename, podErr) -} - -func (s *sourceFile) replaceStore(pods ...*v1.Pod) (err error) { - objs := []interface{}{} - for _, pod := range pods { - objs = append(objs, pod) - } - return s.store.Replace(objs, "") -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go deleted file mode 100644 index 42d86f868..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_linux.go +++ /dev/null @@ -1,154 +0,0 @@ -//go:build linux -// +build linux - -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "fmt" - "os" - "path/filepath" - "strings" - "time" - - "github.com/fsnotify/fsnotify" - "k8s.io/klog/v2" - - "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/client-go/util/flowcontrol" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" -) - -const ( - retryPeriod = 1 * time.Second - maxRetryPeriod = 20 * time.Second -) - -type retryableError struct { - message string -} - -func (e *retryableError) Error() string { - return e.message -} - -func (s *sourceFile) startWatch() { - backOff := flowcontrol.NewBackOff(retryPeriod, maxRetryPeriod) - backOffID := "watch" - - go wait.Forever(func() { - if backOff.IsInBackOffSinceUpdate(backOffID, time.Now()) { - return - } - - if err := s.doWatch(); err != nil { - klog.ErrorS(err, "Unable to read config path", "path", s.path) - if _, retryable := err.(*retryableError); !retryable { - backOff.Next(backOffID, time.Now()) - } - } - }, retryPeriod) -} - -func (s *sourceFile) doWatch() error { - _, err := os.Stat(s.path) - if err != nil { - if !os.IsNotExist(err) { - return err - } - // Emit an update with an empty PodList to allow FileSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{}, Op: kubetypes.SET, Source: kubetypes.FileSource} - return &retryableError{"path does not exist, ignoring"} - } - - w, err := fsnotify.NewWatcher() - if err != nil { - return fmt.Errorf("unable to create inotify: %v", err) - } - defer w.Close() - - err = w.Add(s.path) - if err != nil { - return fmt.Errorf("unable to create inotify for path %q: %v", s.path, err) - } - - for { - select { - case event := <-w.Events: - if err = s.produceWatchEvent(&event); err != nil { - return fmt.Errorf("error while processing inotify event (%+v): %v", event, err) - } - case err = <-w.Errors: - return fmt.Errorf("error while watching %q: %v", s.path, err) - } - } -} - -func (s *sourceFile) produceWatchEvent(e *fsnotify.Event) error { - // Ignore file start with dots - if strings.HasPrefix(filepath.Base(e.Name), ".") { - klog.V(4).InfoS("Ignored pod manifest, because it starts with dots", "eventName", e.Name) - return nil - } - var eventType podEventType - switch { - case (e.Op & fsnotify.Create) > 0: - eventType = podAdd - case (e.Op & fsnotify.Write) > 0: - eventType = podModify - case (e.Op & fsnotify.Chmod) > 0: - eventType = podModify - case (e.Op & fsnotify.Remove) > 0: - eventType = podDelete - case (e.Op & fsnotify.Rename) > 0: - eventType = podDelete - default: - // Ignore rest events - return nil - } - - s.watchEvents <- &watchEvent{e.Name, eventType} - return nil -} - -func (s *sourceFile) consumeWatchEvent(e *watchEvent) error { - switch e.eventType { - case podAdd, podModify: - pod, err := s.extractFromFile(e.fileName) - if err != nil { - return fmt.Errorf("can't process config file %q: %v", e.fileName, err) - } - return s.store.Add(pod) - case podDelete: - if objKey, keyExist := s.fileKeyMapping[e.fileName]; keyExist { - pod, podExist, err := s.store.GetByKey(objKey) - if err != nil { - return err - } - if !podExist { - return fmt.Errorf("the pod with key %s doesn't exist in cache", objKey) - } - if err = s.store.Delete(pod); err != nil { - return fmt.Errorf("failed to remove deleted pod from cache: %v", err) - } - delete(s.fileKeyMapping, e.fileName) - } - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go deleted file mode 100644 index 7d5c77c28..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/file_unsupported.go +++ /dev/null @@ -1,34 +0,0 @@ -//go:build !linux -// +build !linux - -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "fmt" - - "k8s.io/klog/v2" -) - -func (s *sourceFile) startWatch() { - klog.ErrorS(nil, "Watching source file is unsupported in this build") -} - -func (s *sourceFile) consumeWatchEvent(e *watchEvent) error { - return fmt.Errorf("consuming watch event is unsupported in this build") -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/flags.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/flags.go deleted file mode 100644 index 4ff13cacf..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/flags.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "fmt" - - "github.com/spf13/pflag" -) - -// ContainerRuntimeOptions defines options for the container runtime. -type ContainerRuntimeOptions struct { - // General Options. - - // RuntimeCgroups that container runtime is expected to be isolated in. - RuntimeCgroups string - // PodSandboxImage is the image whose network/ipc namespaces - // containers in each pod will use. - PodSandboxImage string - // Image credential provider plugin options - - // ImageCredentialProviderConfigFile is the path to the credential provider plugin config file. - // This config file is a specification for what credential providers are enabled and invoked - // by the kubelet. The plugin config should contain information about what plugin binary - // to execute and what container images the plugin should be called for. - // +optional - ImageCredentialProviderConfigFile string - // ImageCredentialProviderBinDir is the path to the directory where credential provider plugin - // binaries exist. The name of each plugin binary is expected to match the name of the plugin - // specified in imageCredentialProviderConfigFile. - // +optional - ImageCredentialProviderBinDir string -} - -// AddFlags adds flags to the container runtime, according to ContainerRuntimeOptions. -func (s *ContainerRuntimeOptions) AddFlags(fs *pflag.FlagSet) { - // General settings. - fs.StringVar(&s.RuntimeCgroups, "runtime-cgroups", s.RuntimeCgroups, "Optional absolute name of cgroups to create and run the runtime in.") - fs.StringVar(&s.PodSandboxImage, "pod-infra-container-image", s.PodSandboxImage, fmt.Sprintf("Specified image will not be pruned by the image garbage collector. CRI implementations have their own configuration to set this image.")) - _ = fs.MarkDeprecated("pod-infra-container-image", "will be removed in 1.35. Image garbage collector will get sandbox image information from CRI.") - - // Image credential provider settings. - fs.StringVar(&s.ImageCredentialProviderConfigFile, "image-credential-provider-config", s.ImageCredentialProviderConfigFile, "The path to the credential provider plugin config file.") - fs.StringVar(&s.ImageCredentialProviderBinDir, "image-credential-provider-bin-dir", s.ImageCredentialProviderBinDir, "The path to the directory where credential provider plugin binaries are located.") -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go deleted file mode 100644 index b37608781..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/http.go +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "bytes" - "fmt" - "net/http" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/wait" - api "k8s.io/kubernetes/pkg/apis/core" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" - - "k8s.io/apimachinery/pkg/types" - "k8s.io/klog/v2" - utilio "k8s.io/utils/io" -) - -type sourceURL struct { - url string - header http.Header - nodeName types.NodeName - updates chan<- interface{} - data []byte - failureLogs int - client *http.Client -} - -// NewSourceURL specifies the URL where to read the Pod configuration from, then watches it for changes. -func NewSourceURL(url string, header http.Header, nodeName types.NodeName, period time.Duration, updates chan<- interface{}) { - config := &sourceURL{ - url: url, - header: header, - nodeName: nodeName, - updates: updates, - data: nil, - // Timing out requests leads to retries. This client is only used to - // read the manifest URL passed to kubelet. - client: &http.Client{Timeout: 10 * time.Second}, - } - klog.V(1).InfoS("Watching URL", "URL", url) - go wait.Until(config.run, period, wait.NeverStop) -} - -func (s *sourceURL) run() { - if err := s.extractFromURL(); err != nil { - // Don't log this multiple times per minute. The first few entries should be - // enough to get the point across. - if s.failureLogs < 3 { - klog.InfoS("Failed to read pods from URL", "err", err) - } else if s.failureLogs == 3 { - klog.InfoS("Failed to read pods from URL. Dropping verbosity of this message to V(4)", "err", err) - } else { - klog.V(4).InfoS("Failed to read pods from URL", "err", err) - } - s.failureLogs++ - } else { - if s.failureLogs > 0 { - klog.InfoS("Successfully read pods from URL") - s.failureLogs = 0 - } - } -} - -func (s *sourceURL) applyDefaults(pod *api.Pod) error { - return applyDefaults(pod, s.url, false, s.nodeName) -} - -func (s *sourceURL) extractFromURL() error { - req, err := http.NewRequest("GET", s.url, nil) - if err != nil { - return err - } - req.Header = s.header - resp, err := s.client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - data, err := utilio.ReadAtMost(resp.Body, maxConfigLength) - if err != nil { - return err - } - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("%v: %v", s.url, resp.Status) - } - if len(data) == 0 { - // Emit an update with an empty PodList to allow HTTPSource to be marked as seen - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{}, Op: kubetypes.SET, Source: kubetypes.HTTPSource} - return fmt.Errorf("zero-length data received from %v", s.url) - } - // Short circuit if the data has not changed since the last time it was read. - if bytes.Equal(data, s.data) { - return nil - } - s.data = data - - // First try as it is a single pod. - parsed, pod, singlePodErr := tryDecodeSinglePod(data, s.applyDefaults) - if parsed { - if singlePodErr != nil { - // It parsed but could not be used. - return singlePodErr - } - s.updates <- kubetypes.PodUpdate{Pods: []*v1.Pod{pod}, Op: kubetypes.SET, Source: kubetypes.HTTPSource} - return nil - } - - // That didn't work, so try a list of pods. - parsed, podList, multiPodErr := tryDecodePodList(data, s.applyDefaults) - if parsed { - if multiPodErr != nil { - // It parsed but could not be used. - return multiPodErr - } - pods := make([]*v1.Pod, 0, len(podList.Items)) - for i := range podList.Items { - pods = append(pods, &podList.Items[i]) - } - s.updates <- kubetypes.PodUpdate{Pods: pods, Op: kubetypes.SET, Source: kubetypes.HTTPSource} - return nil - } - - return fmt.Errorf("%v: received '%v', but couldn't parse as "+ - "single (%v) or multiple pods (%v)", - s.url, string(data), singlePodErr, multiPodErr) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go deleted file mode 100644 index a2b3e1e0a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/mux.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "context" - "sync" - - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/klog/v2" -) - -type merger interface { - // Invoked when a change from a source is received. May also function as an incremental - // merger if you wish to consume changes incrementally. Must be reentrant when more than - // one source is defined. - Merge(source string, update interface{}) error -} - -// mux is a class for merging configuration from multiple sources. Changes are -// pushed via channels and sent to the merge function. -type mux struct { - // Invoked when an update is sent to a source. - merger merger - - // Sources and their lock. - sourceLock sync.RWMutex - // Maps source names to channels - sources map[string]chan interface{} -} - -// newMux creates a new mux that can merge changes from multiple sources. -func newMux(merger merger) *mux { - mux := &mux{ - sources: make(map[string]chan interface{}), - merger: merger, - } - return mux -} - -// ChannelWithContext returns a channel where a configuration source -// can send updates of new configurations. Multiple calls with the same -// source will return the same channel. This allows change and state based sources -// to use the same channel. Different source names however will be treated as a -// union. -func (m *mux) ChannelWithContext(ctx context.Context, source string) chan interface{} { - if len(source) == 0 { - panic("Channel given an empty name") - } - m.sourceLock.Lock() - defer m.sourceLock.Unlock() - channel, exists := m.sources[source] - if exists { - return channel - } - newChannel := make(chan interface{}) - m.sources[source] = newChannel - - go wait.Until(func() { m.listen(source, newChannel) }, 0, ctx.Done()) - return newChannel -} - -func (m *mux) listen(source string, listenChannel <-chan interface{}) { - for update := range listenChannel { - if err := m.merger.Merge(source, update); err != nil { - klog.InfoS("failed merging update", "err", err) - } - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/config/sources.go b/vendor/k8s.io/kubernetes/pkg/kubelet/config/sources.go deleted file mode 100644 index f1ce89add..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/config/sources.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package config implements the pod configuration readers. -package config - -import ( - "sync" - - "k8s.io/apimachinery/pkg/util/sets" -) - -// SourcesReadyFn is function that returns true if the specified sources have been seen. -type SourcesReadyFn func(sourcesSeen sets.Set[string]) bool - -// SourcesReady tracks the set of configured sources seen by the kubelet. -type SourcesReady interface { - // AddSource adds the specified source to the set of sources managed. - AddSource(source string) - // AllReady returns true if the currently configured sources have all been seen. - AllReady() bool -} - -// NewSourcesReady returns a SourcesReady with the specified function. -func NewSourcesReady(sourcesReadyFn SourcesReadyFn) SourcesReady { - return &sourcesImpl{ - sourcesSeen: sets.New[string](), - sourcesReadyFn: sourcesReadyFn, - } -} - -// sourcesImpl implements SourcesReady. It is thread-safe. -type sourcesImpl struct { - // lock protects access to sources seen. - lock sync.RWMutex - // set of sources seen. - sourcesSeen sets.Set[string] - // sourcesReady is a function that evaluates if the sources are ready. - sourcesReadyFn SourcesReadyFn -} - -// Add adds the specified source to the set of sources managed. -func (s *sourcesImpl) AddSource(source string) { - s.lock.Lock() - defer s.lock.Unlock() - s.sourcesSeen.Insert(source) -} - -// AllReady returns true if each configured source is ready. -func (s *sourcesImpl) AllReady() bool { - s.lock.RLock() - defer s.lock.RUnlock() - return s.sourcesReadyFn(s.sourcesSeen) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/.mockery.yaml b/vendor/k8s.io/kubernetes/pkg/kubelet/container/.mockery.yaml deleted file mode 100644 index 84489a009..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/.mockery.yaml +++ /dev/null @@ -1,18 +0,0 @@ ---- -dir: testing -filename: "mock_{{.InterfaceName | snakecase}}.go" -boilerplate-file: ../../../hack/boilerplate/boilerplate.generatego.txt -outpkg: testing -with-expecter: true -packages: - io/fs: - interfaces: - DirEntry: - config: - filename: mockdirentry.go - k8s.io/kubernetes/pkg/kubelet/container: - interfaces: - Runtime: - config: - filename: runtime_mock.go - RuntimeCache: diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go deleted file mode 100644 index 9b4138634..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/cache.go +++ /dev/null @@ -1,214 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "sync" - "time" - - "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" -) - -// Cache stores the PodStatus for the pods. It represents *all* the visible -// pods/containers in the container runtime. All cache entries are at least as -// new or newer than the global timestamp (set by UpdateTime()), while -// individual entries may be slightly newer than the global timestamp. If a pod -// has no states known by the runtime, Cache returns an empty PodStatus object -// with ID populated. -// -// Cache provides two methods to retrieve the PodStatus: the non-blocking Get() -// and the blocking GetNewerThan() method. The component responsible for -// populating the cache is expected to call Delete() to explicitly free the -// cache entries. -type Cache interface { - Get(types.UID) (*PodStatus, error) - // Set updates the cache by setting the PodStatus for the pod only - // if the data is newer than the cache based on the provided - // time stamp. Returns if the cache was updated. - Set(types.UID, *PodStatus, error, time.Time) (updated bool) - // GetNewerThan is a blocking call that only returns the status - // when it is newer than the given time. - GetNewerThan(types.UID, time.Time) (*PodStatus, error) - Delete(types.UID) - UpdateTime(time.Time) -} - -type data struct { - // Status of the pod. - status *PodStatus - // Error got when trying to inspect the pod. - err error - // Time when the data was last modified. - modified time.Time -} - -type subRecord struct { - time time.Time - ch chan *data -} - -// cache implements Cache. -type cache struct { - // Lock which guards all internal data structures. - lock sync.RWMutex - // Map that stores the pod statuses. - pods map[types.UID]*data - // A global timestamp represents how fresh the cached data is. All - // cache content is at the least newer than this timestamp. Note that the - // timestamp is nil after initialization, and will only become non-nil when - // it is ready to serve the cached statuses. - timestamp *time.Time - // Map that stores the subscriber records. - subscribers map[types.UID][]*subRecord -} - -// NewCache creates a pod cache. -func NewCache() Cache { - return &cache{pods: map[types.UID]*data{}, subscribers: map[types.UID][]*subRecord{}} -} - -// Get returns the PodStatus for the pod; callers are expected not to -// modify the objects returned. -func (c *cache) Get(id types.UID) (*PodStatus, error) { - c.lock.RLock() - defer c.lock.RUnlock() - d := c.get(id) - return d.status, d.err -} - -func (c *cache) GetNewerThan(id types.UID, minTime time.Time) (*PodStatus, error) { - ch := c.subscribe(id, minTime) - d := <-ch - return d.status, d.err -} - -// Set sets the PodStatus for the pod only if the data is newer than the cache -func (c *cache) Set(id types.UID, status *PodStatus, err error, timestamp time.Time) (updated bool) { - c.lock.Lock() - defer c.lock.Unlock() - - if utilfeature.DefaultFeatureGate.Enabled(features.EventedPLEG) { - // Set the value in the cache only if it's not present already - // or the timestamp in the cache is older than the current update timestamp - if cachedVal, ok := c.pods[id]; ok && cachedVal.modified.After(timestamp) { - return false - } - } - - c.pods[id] = &data{status: status, err: err, modified: timestamp} - c.notify(id, timestamp) - return true -} - -// Delete removes the entry of the pod. -func (c *cache) Delete(id types.UID) { - c.lock.Lock() - defer c.lock.Unlock() - delete(c.pods, id) -} - -// UpdateTime modifies the global timestamp of the cache and notify -// subscribers if needed. -func (c *cache) UpdateTime(timestamp time.Time) { - c.lock.Lock() - defer c.lock.Unlock() - c.timestamp = ×tamp - // Notify all the subscribers if the condition is met. - for id := range c.subscribers { - c.notify(id, *c.timestamp) - } -} - -func makeDefaultData(id types.UID) *data { - return &data{status: &PodStatus{ID: id}, err: nil} -} - -func (c *cache) get(id types.UID) *data { - d, ok := c.pods[id] - if !ok { - // Cache should store *all* pod/container information known by the - // container runtime. A cache miss indicates that there are no states - // regarding the pod last time we queried the container runtime. - // What this *really* means is that there are no visible pod/containers - // associated with this pod. Simply return an default (mostly empty) - // PodStatus to reflect this. - return makeDefaultData(id) - } - return d -} - -// getIfNewerThan returns the data it is newer than the given time. -// Otherwise, it returns nil. The caller should acquire the lock. -func (c *cache) getIfNewerThan(id types.UID, minTime time.Time) *data { - d, ok := c.pods[id] - globalTimestampIsNewer := (c.timestamp != nil && c.timestamp.After(minTime)) - if !ok && globalTimestampIsNewer { - // Status is not cached, but the global timestamp is newer than - // minTime, return the default status. - return makeDefaultData(id) - } - if ok && (d.modified.After(minTime) || globalTimestampIsNewer) { - // Status is cached, return status if either of the following is true. - // * status was modified after minTime - // * the global timestamp of the cache is newer than minTime. - return d - } - // The pod status is not ready. - return nil -} - -// notify sends notifications for pod with the given id, if the requirements -// are met. Note that the caller should acquire the lock. -func (c *cache) notify(id types.UID, timestamp time.Time) { - list, ok := c.subscribers[id] - if !ok { - // No one to notify. - return - } - newList := []*subRecord{} - for i, r := range list { - if timestamp.Before(r.time) { - // Doesn't meet the time requirement; keep the record. - newList = append(newList, list[i]) - continue - } - r.ch <- c.get(id) - close(r.ch) - } - if len(newList) == 0 { - delete(c.subscribers, id) - } else { - c.subscribers[id] = newList - } -} - -func (c *cache) subscribe(id types.UID, timestamp time.Time) chan *data { - ch := make(chan *data, 1) - c.lock.Lock() - defer c.lock.Unlock() - d := c.getIfNewerThan(id, timestamp) - if d != nil { - // If the cache entry is ready, send the data and return immediately. - ch <- d - return ch - } - // Add the subscription record. - c.subscribers[id] = append(c.subscribers[id], &subRecord{time: timestamp, ch: ch}) - return ch -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go deleted file mode 100644 index b0a25d500..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/container_gc.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "context" - "fmt" - "time" - - "k8s.io/klog/v2" -) - -// GCPolicy specifies a policy for garbage collecting containers. -type GCPolicy struct { - // Minimum age at which a container can be garbage collected, zero for no limit. - MinAge time.Duration - - // Max number of dead containers any single pod (UID, container name) pair is - // allowed to have, less than zero for no limit. - MaxPerPodContainer int - - // Max number of total dead containers, less than zero for no limit. - MaxContainers int -} - -// GC manages garbage collection of dead containers. -// -// Implementation is thread-compatible. -type GC interface { - // Garbage collect containers. - GarbageCollect(ctx context.Context) error - // Deletes all unused containers, including containers belonging to pods that are terminated but not deleted - DeleteAllUnusedContainers(ctx context.Context) error -} - -// SourcesReadyProvider knows how to determine if configuration sources are ready -type SourcesReadyProvider interface { - // AllReady returns true if the currently configured sources have all been seen. - AllReady() bool -} - -// TODO(vmarmol): Preferentially remove pod infra containers. -type realContainerGC struct { - // Container runtime - runtime Runtime - - // Policy for garbage collection. - policy GCPolicy - - // sourcesReadyProvider provides the readiness of kubelet configuration sources. - sourcesReadyProvider SourcesReadyProvider -} - -// NewContainerGC creates a new instance of GC with the specified policy. -func NewContainerGC(runtime Runtime, policy GCPolicy, sourcesReadyProvider SourcesReadyProvider) (GC, error) { - if policy.MinAge < 0 { - return nil, fmt.Errorf("invalid minimum garbage collection age: %v", policy.MinAge) - } - - return &realContainerGC{ - runtime: runtime, - policy: policy, - sourcesReadyProvider: sourcesReadyProvider, - }, nil -} - -func (cgc *realContainerGC) GarbageCollect(ctx context.Context) error { - return cgc.runtime.GarbageCollect(ctx, cgc.policy, cgc.sourcesReadyProvider.AllReady(), false) -} - -func (cgc *realContainerGC) DeleteAllUnusedContainers(ctx context.Context) error { - klog.InfoS("Attempting to delete unused containers") - return cgc.runtime.GarbageCollect(ctx, cgc.policy, cgc.sourcesReadyProvider.AllReady(), true) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go deleted file mode 100644 index 9e6780310..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/helpers.go +++ /dev/null @@ -1,444 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "context" - "encoding/json" - "fmt" - "hash/fnv" - "strings" - - "k8s.io/klog/v2" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/tools/record" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - sc "k8s.io/kubernetes/pkg/securitycontext" - hashutil "k8s.io/kubernetes/pkg/util/hash" - "k8s.io/kubernetes/third_party/forked/golang/expansion" - utilsnet "k8s.io/utils/net" -) - -// HandlerRunner runs a lifecycle handler for a container. -type HandlerRunner interface { - Run(ctx context.Context, containerID ContainerID, pod *v1.Pod, container *v1.Container, handler *v1.LifecycleHandler) (string, error) -} - -// RuntimeHelper wraps kubelet to make container runtime -// able to get necessary informations like the RunContainerOptions, DNS settings, Host IP. -type RuntimeHelper interface { - GenerateRunContainerOptions(ctx context.Context, pod *v1.Pod, container *v1.Container, podIP string, podIPs []string, imageVolumes ImageVolumes) (contOpts *RunContainerOptions, cleanupAction func(), err error) - GetPodDNS(pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error) - // GetPodCgroupParent returns the CgroupName identifier, and its literal cgroupfs form on the host - // of a pod. - GetPodCgroupParent(pod *v1.Pod) string - GetPodDir(podUID types.UID) string - GeneratePodHostNameAndDomain(pod *v1.Pod) (hostname string, hostDomain string, err error) - // GetExtraSupplementalGroupsForPod returns a list of the extra - // supplemental groups for the Pod. These extra supplemental groups come - // from annotations on persistent volumes that the pod depends on. - GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int64 - - // GetOrCreateUserNamespaceMappings returns the configuration for the sandbox user namespace - GetOrCreateUserNamespaceMappings(pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) - - // PrepareDynamicResources prepares resources for a pod. - PrepareDynamicResources(ctx context.Context, pod *v1.Pod) error - - // UnprepareDynamicResources unprepares resources for a a pod. - UnprepareDynamicResources(ctx context.Context, pod *v1.Pod) error - - // SetPodWatchCondition flags a pod to be inspected until the condition is met. - SetPodWatchCondition(types.UID, string, func(*PodStatus) bool) -} - -// ShouldContainerBeRestarted checks whether a container needs to be restarted. -// TODO(yifan): Think about how to refactor this. -func ShouldContainerBeRestarted(container *v1.Container, pod *v1.Pod, podStatus *PodStatus) bool { - // Once a pod has been marked deleted, it should not be restarted - if pod.DeletionTimestamp != nil { - return false - } - // Get latest container status. - status := podStatus.FindContainerStatusByName(container.Name) - // If the container was never started before, we should start it. - // NOTE(random-liu): If all historical containers were GC'd, we'll also return true here. - if status == nil { - return true - } - // Check whether container is running - if status.State == ContainerStateRunning { - return false - } - // Always restart container in the unknown, or in the created state. - if status.State == ContainerStateUnknown || status.State == ContainerStateCreated { - return true - } - // Check RestartPolicy for dead container - if pod.Spec.RestartPolicy == v1.RestartPolicyNever { - klog.V(4).InfoS("Already ran container, do nothing", "pod", klog.KObj(pod), "containerName", container.Name) - return false - } - if pod.Spec.RestartPolicy == v1.RestartPolicyOnFailure { - // Check the exit code. - if status.ExitCode == 0 { - klog.V(4).InfoS("Already successfully ran container, do nothing", "pod", klog.KObj(pod), "containerName", container.Name) - return false - } - } - return true -} - -// HashContainer returns the hash of the container. It is used to compare -// the running container with its desired spec. -// Note: remember to update hashValues in container_hash_test.go as well. -func HashContainer(container *v1.Container) uint64 { - hash := fnv.New32a() - containerJSON, _ := json.Marshal(pickFieldsToHash(container)) - hashutil.DeepHashObject(hash, containerJSON) - return uint64(hash.Sum32()) -} - -// pickFieldsToHash pick fields that will affect the running status of the container for hash, -// currently this field range only contains `image` and `name`. -// Note: this list must be updated if ever kubelet wants to allow mutations to other fields. -func pickFieldsToHash(container *v1.Container) map[string]string { - retval := map[string]string{ - "name": container.Name, - "image": container.Image, - } - return retval -} - -// envVarsToMap constructs a map of environment name to value from a slice -// of env vars. -func envVarsToMap(envs []EnvVar) map[string]string { - result := map[string]string{} - for _, env := range envs { - result[env.Name] = env.Value - } - return result -} - -// v1EnvVarsToMap constructs a map of environment name to value from a slice -// of env vars. -func v1EnvVarsToMap(envs []v1.EnvVar) map[string]string { - result := map[string]string{} - for _, env := range envs { - result[env.Name] = env.Value - } - - return result -} - -// ExpandContainerCommandOnlyStatic substitutes only static environment variable values from the -// container environment definitions. This does *not* include valueFrom substitutions. -// TODO: callers should use ExpandContainerCommandAndArgs with a fully resolved list of environment. -func ExpandContainerCommandOnlyStatic(containerCommand []string, envs []v1.EnvVar) (command []string) { - mapping := expansion.MappingFuncFor(v1EnvVarsToMap(envs)) - if len(containerCommand) != 0 { - for _, cmd := range containerCommand { - command = append(command, expansion.Expand(cmd, mapping)) - } - } - return command -} - -// ExpandContainerVolumeMounts expands the subpath of the given VolumeMount by replacing variable references with the values of given EnvVar. -func ExpandContainerVolumeMounts(mount v1.VolumeMount, envs []EnvVar) (string, error) { - - envmap := envVarsToMap(envs) - missingKeys := sets.New[string]() - expanded := expansion.Expand(mount.SubPathExpr, func(key string) string { - value, ok := envmap[key] - if !ok || len(value) == 0 { - missingKeys.Insert(key) - } - return value - }) - - if len(missingKeys) > 0 { - return "", fmt.Errorf("missing value for %s", strings.Join(sets.List(missingKeys), ", ")) - } - return expanded, nil -} - -// ExpandContainerCommandAndArgs expands the given Container's command by replacing variable references `with the values of given EnvVar. -func ExpandContainerCommandAndArgs(container *v1.Container, envs []EnvVar) (command []string, args []string) { - mapping := expansion.MappingFuncFor(envVarsToMap(envs)) - - if len(container.Command) != 0 { - for _, cmd := range container.Command { - command = append(command, expansion.Expand(cmd, mapping)) - } - } - - if len(container.Args) != 0 { - for _, arg := range container.Args { - args = append(args, expansion.Expand(arg, mapping)) - } - } - - return command, args -} - -// FilterEventRecorder creates an event recorder to record object's event except implicitly required container's, like infra container. -func FilterEventRecorder(recorder record.EventRecorder) record.EventRecorder { - return &innerEventRecorder{ - recorder: recorder, - } -} - -type innerEventRecorder struct { - recorder record.EventRecorder -} - -func (irecorder *innerEventRecorder) shouldRecordEvent(object runtime.Object) (*v1.ObjectReference, bool) { - if ref, ok := object.(*v1.ObjectReference); ok { - // this check is needed AFTER the cast. See https://github.com/kubernetes/kubernetes/issues/95552 - if ref == nil { - return nil, false - } - if !strings.HasPrefix(ref.FieldPath, ImplicitContainerPrefix) { - return ref, true - } - } - return nil, false -} - -func (irecorder *innerEventRecorder) Event(object runtime.Object, eventtype, reason, message string) { - if ref, ok := irecorder.shouldRecordEvent(object); ok { - irecorder.recorder.Event(ref, eventtype, reason, message) - } -} - -func (irecorder *innerEventRecorder) Eventf(object runtime.Object, eventtype, reason, messageFmt string, args ...interface{}) { - if ref, ok := irecorder.shouldRecordEvent(object); ok { - irecorder.recorder.Eventf(ref, eventtype, reason, messageFmt, args...) - } - -} - -func (irecorder *innerEventRecorder) AnnotatedEventf(object runtime.Object, annotations map[string]string, eventtype, reason, messageFmt string, args ...interface{}) { - if ref, ok := irecorder.shouldRecordEvent(object); ok { - irecorder.recorder.AnnotatedEventf(ref, annotations, eventtype, reason, messageFmt, args...) - } - -} - -// IsHostNetworkPod returns whether the host networking requested for the given Pod. -// Pod must not be nil. -func IsHostNetworkPod(pod *v1.Pod) bool { - return pod.Spec.HostNetwork -} - -// ConvertPodStatusToRunningPod returns Pod given PodStatus and container runtime string. -// TODO(random-liu): Convert PodStatus to running Pod, should be deprecated soon -func ConvertPodStatusToRunningPod(runtimeName string, podStatus *PodStatus) Pod { - runningPod := Pod{ - ID: podStatus.ID, - Name: podStatus.Name, - Namespace: podStatus.Namespace, - } - for _, containerStatus := range podStatus.ContainerStatuses { - if containerStatus.State != ContainerStateRunning { - continue - } - container := &Container{ - ID: containerStatus.ID, - Name: containerStatus.Name, - Image: containerStatus.Image, - ImageID: containerStatus.ImageID, - ImageRef: containerStatus.ImageRef, - ImageRuntimeHandler: containerStatus.ImageRuntimeHandler, - Hash: containerStatus.Hash, - State: containerStatus.State, - } - runningPod.Containers = append(runningPod.Containers, container) - } - - // Populate sandboxes in kubecontainer.Pod - for _, sandbox := range podStatus.SandboxStatuses { - runningPod.Sandboxes = append(runningPod.Sandboxes, &Container{ - ID: ContainerID{Type: runtimeName, ID: sandbox.Id}, - State: SandboxToContainerState(sandbox.State), - }) - } - return runningPod -} - -// SandboxToContainerState converts runtimeapi.PodSandboxState to -// kubecontainer.State. -// This is only needed because we need to return sandboxes as if they were -// kubecontainer.Containers to avoid substantial changes to PLEG. -// TODO: Remove this once it becomes obsolete. -func SandboxToContainerState(state runtimeapi.PodSandboxState) State { - switch state { - case runtimeapi.PodSandboxState_SANDBOX_READY: - return ContainerStateRunning - case runtimeapi.PodSandboxState_SANDBOX_NOTREADY: - return ContainerStateExited - } - return ContainerStateUnknown -} - -// GetContainerSpec gets the container spec by containerName. -func GetContainerSpec(pod *v1.Pod, containerName string) *v1.Container { - var containerSpec *v1.Container - podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(c *v1.Container, containerType podutil.ContainerType) bool { - if containerName == c.Name { - containerSpec = c - return false - } - return true - }) - return containerSpec -} - -// HasPrivilegedContainer returns true if any of the containers in the pod are privileged. -func HasPrivilegedContainer(pod *v1.Pod) bool { - var hasPrivileged bool - podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(c *v1.Container, containerType podutil.ContainerType) bool { - if c.SecurityContext != nil && c.SecurityContext.Privileged != nil && *c.SecurityContext.Privileged { - hasPrivileged = true - return false - } - return true - }) - return hasPrivileged -} - -// HasWindowsHostProcessContainer returns true if any of the containers in a pod are HostProcess containers. -func HasWindowsHostProcessContainer(pod *v1.Pod) bool { - var hasHostProcess bool - podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(c *v1.Container, containerType podutil.ContainerType) bool { - if sc.HasWindowsHostProcessRequest(pod, c) { - hasHostProcess = true - return false - } - return true - }) - - return hasHostProcess -} - -// AllContainersAreWindowsHostProcess returns true if all containers in a pod are HostProcess containers. -func AllContainersAreWindowsHostProcess(pod *v1.Pod) bool { - allHostProcess := true - podutil.VisitContainers(&pod.Spec, podutil.AllFeatureEnabledContainers(), func(c *v1.Container, containerType podutil.ContainerType) bool { - if !sc.HasWindowsHostProcessRequest(pod, c) { - allHostProcess = false - return false - } - return true - }) - - return allHostProcess -} - -// MakePortMappings creates internal port mapping from api port mapping. -func MakePortMappings(container *v1.Container) (ports []PortMapping) { - names := make(map[string]struct{}) - for _, p := range container.Ports { - pm := PortMapping{ - HostPort: int(p.HostPort), - ContainerPort: int(p.ContainerPort), - Protocol: p.Protocol, - HostIP: p.HostIP, - } - - // We need to determine the address family this entry applies to. We do this to ensure - // duplicate containerPort / protocol rules work across different address families. - // https://github.com/kubernetes/kubernetes/issues/82373 - family := "any" - if p.HostIP != "" { - if utilsnet.IsIPv6String(p.HostIP) { - family = "v6" - } else { - family = "v4" - } - } - - var name = p.Name - if name == "" { - name = fmt.Sprintf("%s-%s-%s:%d:%d", family, p.Protocol, p.HostIP, p.ContainerPort, p.HostPort) - } - - // Protect against a port name being used more than once in a container. - if _, ok := names[name]; ok { - klog.InfoS("Port name conflicted, it is defined more than once", "portName", name) - continue - } - ports = append(ports, pm) - names[name] = struct{}{} - } - return -} - -// HasAnyRegularContainerStarted returns true if any regular container has -// started, which indicates all init containers have been initialized. -// Deprecated: This function is not accurate when its pod sandbox is recreated. -// Use HasAnyActiveRegularContainerStarted instead. -func HasAnyRegularContainerStarted(spec *v1.PodSpec, statuses []v1.ContainerStatus) bool { - if len(statuses) == 0 { - return false - } - - containerNames := make(map[string]struct{}) - for _, c := range spec.Containers { - containerNames[c.Name] = struct{}{} - } - - for _, status := range statuses { - if _, ok := containerNames[status.Name]; !ok { - continue - } - if status.State.Running != nil || status.State.Terminated != nil { - return true - } - } - - return false -} - -// HasAnyActiveRegularContainerStarted returns true if any regular container of -// the current pod sandbox has started, which indicates all init containers -// have been initialized. -func HasAnyActiveRegularContainerStarted(spec *v1.PodSpec, podStatus *PodStatus) bool { - if podStatus == nil { - return false - } - - containerNames := sets.New[string]() - for _, c := range spec.Containers { - containerNames.Insert(c.Name) - } - - for _, status := range podStatus.ActiveContainerStatuses { - if !containerNames.Has(status.Name) { - continue - } - return true - } - - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go deleted file mode 100644 index e0642a0f1..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/os.go +++ /dev/null @@ -1,124 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "os" - "path/filepath" - "time" -) - -// OSInterface collects system level operations that need to be mocked out -// during tests. -type OSInterface interface { - MkdirAll(path string, perm os.FileMode) error - Symlink(oldname string, newname string) error - Stat(path string) (os.FileInfo, error) - Remove(path string) error - RemoveAll(path string) error - Create(path string) (*os.File, error) - Chmod(path string, perm os.FileMode) error - Hostname() (name string, err error) - Chtimes(path string, atime time.Time, mtime time.Time) error - Pipe() (r *os.File, w *os.File, err error) - ReadDir(dirname string) ([]os.DirEntry, error) - Glob(pattern string) ([]string, error) - Open(name string) (*os.File, error) - OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) - Rename(oldpath, newpath string) error -} - -// RealOS is used to dispatch the real system level operations. -type RealOS struct{} - -// MkdirAll will call os.MkdirAll to create a directory. -func (RealOS) MkdirAll(path string, perm os.FileMode) error { - return os.MkdirAll(path, perm) -} - -// Symlink will call os.Symlink to create a symbolic link. -func (RealOS) Symlink(oldname string, newname string) error { - return os.Symlink(oldname, newname) -} - -// Stat will call os.Stat to get the FileInfo for a given path -func (RealOS) Stat(path string) (os.FileInfo, error) { - return os.Stat(path) -} - -// Remove will call os.Remove to remove the path. -func (RealOS) Remove(path string) error { - return os.Remove(path) -} - -// RemoveAll will call os.RemoveAll to remove the path and its children. -func (RealOS) RemoveAll(path string) error { - return os.RemoveAll(path) -} - -// Create will call os.Create to create and return a file -// at path. -func (RealOS) Create(path string) (*os.File, error) { - return os.Create(path) -} - -// Chmod will change the permissions on the specified path or return -// an error. -func (RealOS) Chmod(path string, perm os.FileMode) error { - return os.Chmod(path, perm) -} - -// Hostname will call os.Hostname to return the hostname. -func (RealOS) Hostname() (name string, err error) { - return os.Hostname() -} - -// Chtimes will call os.Chtimes to change the atime and mtime of the path -func (RealOS) Chtimes(path string, atime time.Time, mtime time.Time) error { - return os.Chtimes(path, atime, mtime) -} - -// Pipe will call os.Pipe to return a connected pair of pipe. -func (RealOS) Pipe() (r *os.File, w *os.File, err error) { - return os.Pipe() -} - -// ReadDir will call os.ReadDir to return the files under the directory. -func (RealOS) ReadDir(dirname string) ([]os.DirEntry, error) { - return os.ReadDir(dirname) -} - -// Glob will call filepath.Glob to return the names of all files matching -// pattern. -func (RealOS) Glob(pattern string) ([]string, error) { - return filepath.Glob(pattern) -} - -// Open will call os.Open to return the file. -func (RealOS) Open(name string) (*os.File, error) { - return os.Open(name) -} - -// OpenFile will call os.OpenFile to return the file. -func (RealOS) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) { - return os.OpenFile(name, flag, perm) -} - -// Rename will call os.Rename to rename a file. -func (RealOS) Rename(oldpath, newpath string) error { - return os.Rename(oldpath, newpath) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go deleted file mode 100644 index 3d84a963e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/ref.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - ref "k8s.io/client-go/tools/reference" - "k8s.io/kubernetes/pkg/api/legacyscheme" -) - -// ImplicitContainerPrefix is a container name prefix that will indicate that container was started implicitly (like the pod infra container). -var ImplicitContainerPrefix = "implicitly required container " - -// GenerateContainerRef returns an *v1.ObjectReference which references the given container -// within the given pod. Returns an error if the reference can't be constructed or the -// container doesn't actually belong to the pod. -func GenerateContainerRef(pod *v1.Pod, container *v1.Container) (*v1.ObjectReference, error) { - fieldPath, err := fieldPath(pod, container) - if err != nil { - // TODO: figure out intelligent way to refer to containers that we implicitly - // start (like the pod infra container). This is not a good way, ugh. - fieldPath = ImplicitContainerPrefix + container.Name - } - ref, err := ref.GetPartialReference(legacyscheme.Scheme, pod, fieldPath) - if err != nil { - return nil, err - } - return ref, nil -} - -// fieldPath returns a fieldPath locating container within pod. -// Returns an error if the container isn't part of the pod. -func fieldPath(pod *v1.Pod, container *v1.Container) (string, error) { - for i := range pod.Spec.Containers { - here := &pod.Spec.Containers[i] - if here.Name == container.Name { - if here.Name == "" { - return fmt.Sprintf("spec.containers[%d]", i), nil - } - return fmt.Sprintf("spec.containers{%s}", here.Name), nil - } - } - for i := range pod.Spec.InitContainers { - here := &pod.Spec.InitContainers[i] - if here.Name == container.Name { - if here.Name == "" { - return fmt.Sprintf("spec.initContainers[%d]", i), nil - } - return fmt.Sprintf("spec.initContainers{%s}", here.Name), nil - } - } - for i := range pod.Spec.EphemeralContainers { - here := &pod.Spec.EphemeralContainers[i] - if here.Name == container.Name { - if here.Name == "" { - return fmt.Sprintf("spec.ephemeralContainers[%d]", i), nil - } - return fmt.Sprintf("spec.ephemeralContainers{%s}", here.Name), nil - } - } - return "", fmt.Errorf("container %q not found in pod %s/%s", container.Name, pod.Namespace, pod.Name) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go deleted file mode 100644 index 02f81725f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime.go +++ /dev/null @@ -1,795 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -//go:generate mockery -package container - -import ( - "context" - "fmt" - "io" - "net/url" - "reflect" - "strings" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/tools/remotecommand" - "k8s.io/client-go/util/flowcontrol" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/credentialprovider" - kubelettypes "k8s.io/kubernetes/pkg/kubelet/types" - "k8s.io/kubernetes/pkg/volume" -) - -// Version interface allow to consume the runtime versions - compare and format to string. -type Version interface { - // Compare compares two versions of the runtime. On success it returns -1 - // if the version is less than the other, 1 if it is greater than the other, - // or 0 if they are equal. - Compare(other string) (int, error) - // String returns a string that represents the version. - String() string -} - -// ImageSpec is an internal representation of an image. Currently, it wraps the -// value of a Container's Image field, but in the future it will include more detailed -// information about the different image types. -type ImageSpec struct { - // ID of the image. - Image string - // Runtime handler used to pull this image - RuntimeHandler string - // The annotations for the image. - // This should be passed to CRI during image pulls and returned when images are listed. - Annotations []Annotation -} - -// ImageStats contains statistics about all the images currently available. -type ImageStats struct { - // Total amount of storage consumed by existing images. - TotalStorageBytes uint64 -} - -// Runtime interface defines the interfaces that should be implemented -// by a container runtime. -// Thread safety is required from implementations of this interface. -type Runtime interface { - // Type returns the type of the container runtime. - Type() string - - // Version returns the version information of the container runtime. - Version(ctx context.Context) (Version, error) - - // APIVersion returns the cached API version information of the container - // runtime. Implementation is expected to update this cache periodically. - // This may be different from the runtime engine's version. - // TODO(random-liu): We should fold this into Version() - APIVersion() (Version, error) - // Status returns the status of the runtime. An error is returned if the Status - // function itself fails, nil otherwise. - Status(ctx context.Context) (*RuntimeStatus, error) - // GetPods returns a list of containers grouped by pods. The boolean parameter - // specifies whether the runtime returns all containers including those already - // exited and dead containers (used for garbage collection). - GetPods(ctx context.Context, all bool) ([]*Pod, error) - // GarbageCollect removes dead containers using the specified container gc policy - // If allSourcesReady is not true, it means that kubelet doesn't have the - // complete list of pods from all available sources (e.g., apiserver, http, - // file). In this case, garbage collector should refrain itself from aggressive - // behavior such as removing all containers of unrecognized pods (yet). - // If evictNonDeletedPods is set to true, containers and sandboxes belonging to pods - // that are terminated, but not deleted will be evicted. Otherwise, only deleted pods - // will be GC'd. - // TODO: Revisit this method and make it cleaner. - GarbageCollect(ctx context.Context, gcPolicy GCPolicy, allSourcesReady bool, evictNonDeletedPods bool) error - // SyncPod syncs the running pod into the desired pod. - SyncPod(ctx context.Context, pod *v1.Pod, podStatus *PodStatus, pullSecrets []v1.Secret, backOff *flowcontrol.Backoff) PodSyncResult - // KillPod kills all the containers of a pod. Pod may be nil, running pod must not be. - // TODO(random-liu): Return PodSyncResult in KillPod. - // gracePeriodOverride if specified allows the caller to override the pod default grace period. - // only hard kill paths are allowed to specify a gracePeriodOverride in the kubelet in order to not corrupt user data. - // it is useful when doing SIGKILL for hard eviction scenarios, or max grace period during soft eviction scenarios. - KillPod(ctx context.Context, pod *v1.Pod, runningPod Pod, gracePeriodOverride *int64) error - // GetPodStatus retrieves the status of the pod, including the - // information of all containers in the pod that are visible in Runtime. - GetPodStatus(ctx context.Context, uid types.UID, name, namespace string) (*PodStatus, error) - // TODO(vmarmol): Unify pod and containerID args. - // GetContainerLogs returns logs of a specific container. By - // default, it returns a snapshot of the container log. Set 'follow' to true to - // stream the log. Set 'follow' to false and specify the number of lines (e.g. - // "100" or "all") to tail the log. - GetContainerLogs(ctx context.Context, pod *v1.Pod, containerID ContainerID, logOptions *v1.PodLogOptions, stdout, stderr io.Writer) (err error) - // DeleteContainer deletes a container. If the container is still running, an error is returned. - DeleteContainer(ctx context.Context, containerID ContainerID) error - // ImageService provides methods to image-related methods. - ImageService - // UpdatePodCIDR sends a new podCIDR to the runtime. - // This method just proxies a new runtimeConfig with the updated - // CIDR value down to the runtime shim. - UpdatePodCIDR(ctx context.Context, podCIDR string) error - // CheckpointContainer tells the runtime to checkpoint a container - // and store the resulting archive to the checkpoint directory. - CheckpointContainer(ctx context.Context, options *runtimeapi.CheckpointContainerRequest) error - // Generate pod status from the CRI event - GeneratePodStatus(event *runtimeapi.ContainerEventResponse) (*PodStatus, error) - // ListMetricDescriptors gets the descriptors for the metrics that will be returned in ListPodSandboxMetrics. - // This list should be static at startup: either the client and server restart together when - // adding or removing metrics descriptors, or they should not change. - // Put differently, if ListPodSandboxMetrics references a name that is not described in the initial - // ListMetricDescriptors call, then the metric will not be broadcasted. - ListMetricDescriptors(ctx context.Context) ([]*runtimeapi.MetricDescriptor, error) - // ListPodSandboxMetrics retrieves the metrics for all pod sandboxes. - ListPodSandboxMetrics(ctx context.Context) ([]*runtimeapi.PodSandboxMetrics, error) - // GetContainerStatus returns the status for the container. - GetContainerStatus(ctx context.Context, id ContainerID) (*Status, error) - // GetContainerSwapBehavior reports whether a container could be swappable. - // This is used to decide whether to handle InPlacePodVerticalScaling for containers. - GetContainerSwapBehavior(pod *v1.Pod, container *v1.Container) kubelettypes.SwapBehavior -} - -// StreamingRuntime is the interface implemented by runtimes that handle the serving of the -// streaming calls (exec/attach/port-forward) themselves. In this case, Kubelet should redirect to -// the runtime server. -type StreamingRuntime interface { - GetExec(ctx context.Context, id ContainerID, cmd []string, stdin, stdout, stderr, tty bool) (*url.URL, error) - GetAttach(ctx context.Context, id ContainerID, stdin, stdout, stderr, tty bool) (*url.URL, error) - GetPortForward(ctx context.Context, podName, podNamespace string, podUID types.UID, ports []int32) (*url.URL, error) -} - -// ImageService interfaces allows to work with image service. -type ImageService interface { - // PullImage pulls an image from the network to local storage using the supplied - // secrets if necessary. - // It returns a reference (digest or ID) to the pulled image and the credentials - // that were used to pull the image. If the returned credentials are nil, the - // pull was anonymous. - PullImage(ctx context.Context, image ImageSpec, credentials []credentialprovider.TrackedAuthConfig, podSandboxConfig *runtimeapi.PodSandboxConfig) (string, *credentialprovider.TrackedAuthConfig, error) - // GetImageRef gets the reference (digest or ID) of the image which has already been in - // the local storage. It returns ("", nil) if the image isn't in the local storage. - GetImageRef(ctx context.Context, image ImageSpec) (string, error) - // ListImages gets all images currently on the machine. - ListImages(ctx context.Context) ([]Image, error) - // RemoveImage removes the specified image. - RemoveImage(ctx context.Context, image ImageSpec) error - // ImageStats returns Image statistics. - ImageStats(ctx context.Context) (*ImageStats, error) - // ImageFsInfo returns a list of file systems for containers/images - ImageFsInfo(ctx context.Context) (*runtimeapi.ImageFsInfoResponse, error) - // GetImageSize returns the size of the image - GetImageSize(ctx context.Context, image ImageSpec) (uint64, error) -} - -// Attacher interface allows to attach a container. -type Attacher interface { - AttachContainer(ctx context.Context, id ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool, resize <-chan remotecommand.TerminalSize) (err error) -} - -// CommandRunner interface allows to run command in a container. -type CommandRunner interface { - // RunInContainer synchronously executes the command in the container, and returns the output. - // If the command completes with a non-0 exit code, a k8s.io/utils/exec.ExitError will be returned. - RunInContainer(ctx context.Context, id ContainerID, cmd []string, timeout time.Duration) ([]byte, error) -} - -// Pod is a group of containers. -type Pod struct { - // The ID of the pod, which can be used to retrieve a particular pod - // from the pod list returned by GetPods(). - ID types.UID - // The name and namespace of the pod, which is readable by human. - Name string - Namespace string - // Creation timestamps of the Pod in nanoseconds. - CreatedAt uint64 - // List of containers that belongs to this pod. It may contain only - // running containers, or mixed with dead ones (when GetPods(true)). - Containers []*Container - // List of sandboxes associated with this pod. The sandboxes are converted - // to Container temporarily to avoid substantial changes to other - // components. This is only populated by kuberuntime. - // TODO: use the runtimeApi.PodSandbox type directly. - Sandboxes []*Container -} - -// PodPair contains both runtime#Pod and api#Pod -type PodPair struct { - // APIPod is the v1.Pod - APIPod *v1.Pod - // RunningPod is the pod defined in pkg/kubelet/container/runtime#Pod - RunningPod *Pod -} - -// ContainerID is a type that identifies a container. -type ContainerID struct { - // The type of the container runtime. e.g. 'docker'. - Type string - // The identification of the container, this is comsumable by - // the underlying container runtime. (Note that the container - // runtime interface still takes the whole struct as input). - ID string -} - -// BuildContainerID returns the ContainerID given type and id. -func BuildContainerID(typ, ID string) ContainerID { - return ContainerID{Type: typ, ID: ID} -} - -// ParseContainerID is a convenience method for creating a ContainerID from an ID string. -func ParseContainerID(containerID string) ContainerID { - var id ContainerID - if err := id.ParseString(containerID); err != nil { - klog.ErrorS(err, "Parsing containerID failed") - } - return id -} - -// ParseString converts given string into ContainerID -func (c *ContainerID) ParseString(data string) error { - // Trim the quotes and split the type and ID. - parts := strings.Split(strings.Trim(data, "\""), "://") - if len(parts) != 2 { - return fmt.Errorf("invalid container ID: %q", data) - } - c.Type, c.ID = parts[0], parts[1] - return nil -} - -func (c *ContainerID) String() string { - return fmt.Sprintf("%s://%s", c.Type, c.ID) -} - -// IsEmpty returns whether given ContainerID is empty. -func (c *ContainerID) IsEmpty() bool { - return *c == ContainerID{} -} - -// MarshalJSON formats a given ContainerID into a byte array. -func (c *ContainerID) MarshalJSON() ([]byte, error) { - return []byte(fmt.Sprintf("%q", c.String())), nil -} - -// UnmarshalJSON parses ContainerID from a given array of bytes. -func (c *ContainerID) UnmarshalJSON(data []byte) error { - return c.ParseString(string(data)) -} - -// State represents the state of a container -type State string - -const ( - // ContainerStateCreated indicates a container that has been created (e.g. with docker create) but not started. - ContainerStateCreated State = "created" - // ContainerStateRunning indicates a currently running container. - ContainerStateRunning State = "running" - // ContainerStateExited indicates a container that ran and completed ("stopped" in other contexts, although a created container is technically also "stopped"). - ContainerStateExited State = "exited" - // ContainerStateUnknown encompasses all the states that we currently don't care about (like restarting, paused, dead). - ContainerStateUnknown State = "unknown" -) - -// ContainerReasonStatusUnknown indicates a container the status of the container cannot be determined. -const ContainerReasonStatusUnknown string = "ContainerStatusUnknown" - -// Container provides the runtime information for a container, such as ID, hash, -// state of the container. -type Container struct { - // The ID of the container, used by the container runtime to identify - // a container. - ID ContainerID - // The name of the container, which should be the same as specified by - // v1.Container. - Name string - // The image name of the container, this also includes the tag of the image, - // the expected form is "NAME:TAG". - Image string - // The id of the image used by the container. - ImageID string - // The digested reference of the image used by the container. - ImageRef string - // Runtime handler used to pull the image if any. - ImageRuntimeHandler string - // Hash of the container, used for comparison. Optional for containers - // not managed by kubelet. - Hash uint64 - // State is the state of the container. - State State -} - -// PodStatus represents the status of the pod and its containers. -// v1.PodStatus can be derived from examining PodStatus and v1.Pod. -type PodStatus struct { - // ID of the pod. - ID types.UID - // Name of the pod. - Name string - // Namespace of the pod. - Namespace string - // All IPs assigned to this pod - IPs []string - // Status of containers in the pod. - ContainerStatuses []*Status - // Statuses of containers of the active sandbox in the pod. - ActiveContainerStatuses []*Status - // Status of the pod sandbox. - // Only for kuberuntime now, other runtime may keep it nil. - SandboxStatuses []*runtimeapi.PodSandboxStatus - // Timestamp at which container and pod statuses were recorded - TimeStamp time.Time -} - -// ContainerResources represents the Resources allocated to the running container. -type ContainerResources struct { - // CPU capacity reserved for the container - CPURequest *resource.Quantity - // CPU limit enforced on the container - CPULimit *resource.Quantity - // Memory capaacity reserved for the container - MemoryRequest *resource.Quantity - // Memory limit enforced on the container - MemoryLimit *resource.Quantity -} - -// Status represents the status of a container. -// -// Status does not contain VolumeMap because CRI API is unaware of volume names. -type Status struct { - // ID of the container. - ID ContainerID - // Name of the container. - Name string - // Status of the container. - State State - // Creation time of the container. - CreatedAt time.Time - // Start time of the container. - StartedAt time.Time - // Finish time of the container. - FinishedAt time.Time - // Exit code of the container. - ExitCode int - // Name of the image, this also includes the tag of the image, - // the expected form is "NAME:TAG". - Image string - // ID of the image. - ImageID string - // The digested reference of the image used by the container. - ImageRef string - // Runtime handler used to pull the image if any. - ImageRuntimeHandler string - // Hash of the container, used for comparison. - Hash uint64 - // Number of times that the container has been restarted. - RestartCount int - // A string explains why container is in such a status. - Reason string - // Message written by the container before exiting (stored in - // TerminationMessagePath). - Message string - // CPU and memory resources for this container - Resources *ContainerResources - // User identity information of the first process of this container - User *ContainerUser - // Mounts are the volume mounts of the container - Mounts []Mount - // StopSignal is used to show the container's effective stop signal in the Status - StopSignal *v1.Signal -} - -// ContainerUser represents user identity information -type ContainerUser struct { - // Linux holds user identity information of the first process of the containers in Linux. - // Note that this field cannot be set when spec.os.name is windows. - Linux *LinuxContainerUser - - // Windows holds user identity information of the first process of the containers in Windows - // This is just reserved for future use. - // Windows *WindowsContainerUser -} - -// LinuxContainerUser represents user identity information in Linux containers -type LinuxContainerUser struct { - // UID is the primary uid of the first process in the container - UID int64 - // GID is the primary gid of the first process in the container - GID int64 - // SupplementalGroups are the supplemental groups attached to the first process in the container - SupplementalGroups []int64 -} - -// FindContainerStatusByName returns container status in the pod status with the given name. -// When there are multiple containers' statuses with the same name, the first match will be returned. -func (podStatus *PodStatus) FindContainerStatusByName(containerName string) *Status { - for _, containerStatus := range podStatus.ContainerStatuses { - if containerStatus.Name == containerName { - return containerStatus - } - } - return nil -} - -// GetRunningContainerStatuses returns container status of all the running containers in a pod -func (podStatus *PodStatus) GetRunningContainerStatuses() []*Status { - runningContainerStatuses := []*Status{} - for _, containerStatus := range podStatus.ContainerStatuses { - if containerStatus.State == ContainerStateRunning { - runningContainerStatuses = append(runningContainerStatuses, containerStatus) - } - } - return runningContainerStatuses -} - -// Image contains basic information about a container image. -type Image struct { - // ID of the image. - ID string - // Other names by which this image is known. - RepoTags []string - // Digests by which this image is known. - RepoDigests []string - // The size of the image in bytes. - Size int64 - // ImageSpec for the image which include annotations. - Spec ImageSpec - // Pin for preventing garbage collection - Pinned bool -} - -// EnvVar represents the environment variable. -type EnvVar struct { - Name string - Value string -} - -// Annotation represents an annotation. -type Annotation struct { - Name string - Value string -} - -// Mount represents a volume mount. -type Mount struct { - // Name of the volume mount. - // TODO(yifan): Remove this field, as this is not representing the unique name of the mount, - // but the volume name only. - Name string - // Path of the mount within the container. - ContainerPath string - // Path of the mount on the host. - HostPath string - // Whether the mount is read-only. - ReadOnly bool - // Whether the mount is recursive read-only. - // Must not be true if ReadOnly is false. - RecursiveReadOnly bool - // Whether the mount needs SELinux relabeling - SELinuxRelabel bool - // Requested propagation mode - Propagation runtimeapi.MountPropagation - // Image is set if an OCI volume as image ID or digest should get mounted (special case). - Image *runtimeapi.ImageSpec - // ImageSubPath is set if an image volume sub path should get mounted. This - // field is only required if the above Image is set. - ImageSubPath string -} - -// ImageVolumes is a map of image specs by volume name. -type ImageVolumes = map[string]*runtimeapi.ImageSpec - -// PortMapping contains information about the port mapping. -type PortMapping struct { - // Protocol of the port mapping. - Protocol v1.Protocol - // The port number within the container. - ContainerPort int - // The port number on the host. - HostPort int - // The host IP. - HostIP string -} - -// DeviceInfo contains information about the device. -type DeviceInfo struct { - // Path on host for mapping - PathOnHost string - // Path in Container to map - PathInContainer string - // Cgroup permissions - Permissions string -} - -// CDIDevice contains information about CDI device -type CDIDevice struct { - // Name is a fully qualified device name according to - // https://github.com/cncf-tags/container-device-interface/blob/e66544063aa7760c4ea6330ce9e6c757f8e61df2/README.md?plain=1#L9-L15 - Name string -} - -// RunContainerOptions specify the options which are necessary for running containers -type RunContainerOptions struct { - // The environment variables list. - Envs []EnvVar - // The mounts for the containers. - Mounts []Mount - // The host devices mapped into the containers. - Devices []DeviceInfo - // The CDI devices for the container - CDIDevices []CDIDevice - // The annotations for the container - // These annotations are generated by other components (i.e., - // not users). Currently, only device plugins populate the annotations. - Annotations []Annotation - // If the container has specified the TerminationMessagePath, then - // this directory will be used to create and mount the log file to - // container.TerminationMessagePath - PodContainerDir string - // The type of container rootfs - ReadOnly bool -} - -// VolumeInfo contains information about the volume. -type VolumeInfo struct { - // Mounter is the volume's mounter - Mounter volume.Mounter - // BlockVolumeMapper is the Block volume's mapper - BlockVolumeMapper volume.BlockVolumeMapper - // SELinuxLabeled indicates whether this volume has had the - // pod's SELinux label applied to it or not - SELinuxLabeled bool - // Whether the volume permission is set to read-only or not - // This value is passed from volume.spec - ReadOnly bool - // Inner volume spec name, which is the PV name if used, otherwise - // it is the same as the outer volume spec name. - InnerVolumeSpecName string -} - -// VolumeMap represents the map of volumes. -type VolumeMap map[string]VolumeInfo - -// RuntimeConditionType is the types of required runtime conditions. -type RuntimeConditionType string - -const ( - // RuntimeReady means the runtime is up and ready to accept basic containers. - RuntimeReady RuntimeConditionType = "RuntimeReady" - // NetworkReady means the runtime network is up and ready to accept containers which require network. - NetworkReady RuntimeConditionType = "NetworkReady" -) - -// RuntimeStatus contains the status of the runtime. -type RuntimeStatus struct { - // Conditions is an array of current observed runtime conditions. - Conditions []RuntimeCondition - // Handlers is an array of current available handlers - Handlers []RuntimeHandler - // Features is the set of features implemented by the runtime - Features *RuntimeFeatures -} - -// GetRuntimeCondition gets a specified runtime condition from the runtime status. -func (r *RuntimeStatus) GetRuntimeCondition(t RuntimeConditionType) *RuntimeCondition { - for i := range r.Conditions { - c := &r.Conditions[i] - if c.Type == t { - return c - } - } - return nil -} - -// String formats the runtime status into human readable string. -func (r *RuntimeStatus) String() string { - var ss []string - var sh []string - for _, c := range r.Conditions { - ss = append(ss, c.String()) - } - for _, h := range r.Handlers { - sh = append(sh, h.String()) - } - return fmt.Sprintf("Runtime Conditions: %s; Handlers: %s, Features: %s", strings.Join(ss, ", "), strings.Join(sh, ", "), r.Features.String()) -} - -// RuntimeHandler contains condition information for the runtime handler. -type RuntimeHandler struct { - // Name is the handler name. - Name string - // SupportsRecursiveReadOnlyMounts is true if the handler has support for - // recursive read-only mounts. - SupportsRecursiveReadOnlyMounts bool - // SupportsUserNamespaces is true if the handler has support for - // user namespaces. - SupportsUserNamespaces bool -} - -// String formats the runtime handler into human readable string. -func (h *RuntimeHandler) String() string { - return fmt.Sprintf("Name=%s SupportsRecursiveReadOnlyMounts: %v SupportsUserNamespaces: %v", - h.Name, h.SupportsRecursiveReadOnlyMounts, h.SupportsUserNamespaces) -} - -// RuntimeCondition contains condition information for the runtime. -type RuntimeCondition struct { - // Type of runtime condition. - Type RuntimeConditionType - // Status of the condition, one of true/false. - Status bool - // Reason is brief reason for the condition's last transition. - Reason string - // Message is human readable message indicating details about last transition. - Message string -} - -// String formats the runtime condition into human readable string. -func (c *RuntimeCondition) String() string { - return fmt.Sprintf("%s=%t reason:%s message:%s", c.Type, c.Status, c.Reason, c.Message) -} - -// RuntimeFeatures contains the set of features implemented by the runtime -type RuntimeFeatures struct { - SupplementalGroupsPolicy bool -} - -// String formats the runtime condition into a human readable string. -func (f *RuntimeFeatures) String() string { - if f == nil { - return "nil" - } - return fmt.Sprintf("SupplementalGroupsPolicy: %v", f.SupplementalGroupsPolicy) -} - -// Pods represents the list of pods -type Pods []*Pod - -// FindPodByID finds and returns a pod in the pod list by UID. It will return an empty pod -// if not found. -func (p Pods) FindPodByID(podUID types.UID) Pod { - for i := range p { - if p[i].ID == podUID { - return *p[i] - } - } - return Pod{} -} - -// FindPodByFullName finds and returns a pod in the pod list by the full name. -// It will return an empty pod if not found. -func (p Pods) FindPodByFullName(podFullName string) Pod { - for i := range p { - if BuildPodFullName(p[i].Name, p[i].Namespace) == podFullName { - return *p[i] - } - } - return Pod{} -} - -// FindPod combines FindPodByID and FindPodByFullName, it finds and returns a pod in the -// pod list either by the full name or the pod ID. It will return an empty pod -// if not found. -func (p Pods) FindPod(podFullName string, podUID types.UID) Pod { - if len(podFullName) > 0 { - return p.FindPodByFullName(podFullName) - } - return p.FindPodByID(podUID) -} - -// FindContainerByName returns a container in the pod with the given name. -// When there are multiple containers with the same name, the first match will -// be returned. -func (p *Pod) FindContainerByName(containerName string) *Container { - for _, c := range p.Containers { - if c.Name == containerName { - return c - } - } - return nil -} - -// FindContainerByID returns a container in the pod with the given ContainerID. -func (p *Pod) FindContainerByID(id ContainerID) *Container { - for _, c := range p.Containers { - if c.ID == id { - return c - } - } - return nil -} - -// FindSandboxByID returns a sandbox in the pod with the given ContainerID. -func (p *Pod) FindSandboxByID(id ContainerID) *Container { - for _, c := range p.Sandboxes { - if c.ID == id { - return c - } - } - return nil -} - -// ToAPIPod converts Pod to v1.Pod. Note that if a field in v1.Pod has no -// corresponding field in Pod, the field would not be populated. -func (p *Pod) ToAPIPod() *v1.Pod { - var pod v1.Pod - pod.UID = p.ID - pod.Name = p.Name - pod.Namespace = p.Namespace - - for _, c := range p.Containers { - var container v1.Container - container.Name = c.Name - container.Image = c.Image - pod.Spec.Containers = append(pod.Spec.Containers, container) - } - return &pod -} - -// IsEmpty returns true if the pod is empty. -func (p *Pod) IsEmpty() bool { - return reflect.DeepEqual(p, &Pod{}) -} - -// GetPodFullName returns a name that uniquely identifies a pod. -func GetPodFullName(pod *v1.Pod) string { - // Use underscore as the delimiter because it is not allowed in pod name - // (DNS subdomain format), while allowed in the container name format. - return pod.Name + "_" + pod.Namespace -} - -// BuildPodFullName builds the pod full name from pod name and namespace. -func BuildPodFullName(name, namespace string) string { - return name + "_" + namespace -} - -// ParsePodFullName parsed the pod full name. -func ParsePodFullName(podFullName string) (string, string, error) { - parts := strings.Split(podFullName, "_") - if len(parts) != 2 || parts[0] == "" || parts[1] == "" { - return "", "", fmt.Errorf("failed to parse the pod full name %q", podFullName) - } - return parts[0], parts[1], nil -} - -// Option is a functional option type for Runtime, useful for -// completely optional settings. -type Option func(Runtime) - -// SortContainerStatusesByCreationTime sorts the container statuses by creation time. -type SortContainerStatusesByCreationTime []*Status - -func (s SortContainerStatusesByCreationTime) Len() int { return len(s) } -func (s SortContainerStatusesByCreationTime) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s SortContainerStatusesByCreationTime) Less(i, j int) bool { - return s[i].CreatedAt.Before(s[j].CreatedAt) -} - -const ( - // MaxPodTerminationMessageLogLength is the maximum bytes any one pod may have written - // as termination message output across all containers. Containers will be evenly truncated - // until output is below this limit. - MaxPodTerminationMessageLogLength = 1024 * 12 - // MaxContainerTerminationMessageLength is the upper bound any one container may write to - // its termination message path. Contents above this length will be truncated. - MaxContainerTerminationMessageLength = 1024 * 4 - // MaxContainerTerminationMessageLogLength is the maximum bytes any one container will - // have written to its termination message when the message is read from the logs. - MaxContainerTerminationMessageLogLength = 1024 * 2 - // MaxContainerTerminationMessageLogLines is the maximum number of previous lines of - // log output that the termination message can contain. - MaxContainerTerminationMessageLogLines = 80 -) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache.go deleted file mode 100644 index ea4b155e0..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache.go +++ /dev/null @@ -1,97 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -//go:generate mockery -package container - -import ( - "context" - "sync" - "time" -) - -// RuntimeCache is in interface for obtaining cached Pods. -type RuntimeCache interface { - GetPods(context.Context) ([]*Pod, error) - ForceUpdateIfOlder(context.Context, time.Time) error -} - -type podsGetter interface { - GetPods(context.Context, bool) ([]*Pod, error) -} - -// NewRuntimeCache creates a container runtime cache. -func NewRuntimeCache(getter podsGetter, cachePeriod time.Duration) (RuntimeCache, error) { - return &runtimeCache{ - getter: getter, - cachePeriod: cachePeriod, - }, nil -} - -// runtimeCache caches a list of pods. It records a timestamp (cacheTime) right -// before updating the pods, so the timestamp is at most as new as the pods -// (and can be slightly older). The timestamp always moves forward. Callers are -// expected not to modify the pods returned from GetPods. -type runtimeCache struct { - sync.Mutex - // The underlying container runtime used to update the cache. - getter podsGetter - // The interval after which the cache should be refreshed. - cachePeriod time.Duration - // Last time when cache was updated. - cacheTime time.Time - // The content of the cache. - pods []*Pod -} - -// GetPods returns the cached pods if they are not outdated; otherwise, it -// retrieves the latest pods and return them. -func (r *runtimeCache) GetPods(ctx context.Context) ([]*Pod, error) { - r.Lock() - defer r.Unlock() - if time.Since(r.cacheTime) > r.cachePeriod { - if err := r.updateCache(ctx); err != nil { - return nil, err - } - } - return r.pods, nil -} - -func (r *runtimeCache) ForceUpdateIfOlder(ctx context.Context, minExpectedCacheTime time.Time) error { - r.Lock() - defer r.Unlock() - if r.cacheTime.Before(minExpectedCacheTime) { - return r.updateCache(ctx) - } - return nil -} - -func (r *runtimeCache) updateCache(ctx context.Context) error { - pods, timestamp, err := r.getPodsWithTimestamp(ctx) - if err != nil { - return err - } - r.pods, r.cacheTime = pods, timestamp - return nil -} - -// getPodsWithTimestamp records a timestamp and retrieves pods from the getter. -func (r *runtimeCache) getPodsWithTimestamp(ctx context.Context) ([]*Pod, time.Time, error) { - // Always record the timestamp before getting the pods to avoid stale pods. - timestamp := time.Now() - pods, err := r.getter.GetPods(ctx, false) - return pods, timestamp, err -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache_fake.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache_fake.go deleted file mode 100644 index 4a09b3be9..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/runtime_cache_fake.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import "context" - -// TestRuntimeCache embeds runtimeCache with some additional methods for testing. -// It must be declared in the container package to have visibility to runtimeCache. -// It cannot be in a "..._test.go" file in order for runtime_cache_test.go to have cross-package visibility to it. -// (cross-package declarations in test files cannot be used from dot imports if this package is vendored) -type TestRuntimeCache struct { - runtimeCache -} - -// UpdateCacheWithLock updates the cache with the lock. -func (r *TestRuntimeCache) UpdateCacheWithLock() error { - r.Lock() - defer r.Unlock() - return r.updateCache(context.Background()) -} - -// GetCachedPods returns the cached pods. -func (r *TestRuntimeCache) GetCachedPods() []*Pod { - r.Lock() - defer r.Unlock() - return r.pods -} - -// NewTestRuntimeCache creates a new instance of TestRuntimeCache. -func NewTestRuntimeCache(getter podsGetter) *TestRuntimeCache { - return &TestRuntimeCache{ - runtimeCache: runtimeCache{ - getter: getter, - }, - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go b/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go deleted file mode 100644 index b04456e53..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/container/sync_result.go +++ /dev/null @@ -1,138 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package container - -import ( - "errors" - "fmt" - - utilerrors "k8s.io/apimachinery/pkg/util/errors" -) - -// TODO(random-liu): We need to better organize runtime errors for introspection. - -// ErrCrashLoopBackOff returned when a container Terminated and Kubelet is backing off the restart. -var ErrCrashLoopBackOff = errors.New("CrashLoopBackOff") - -var ( - // ErrContainerNotFound returned when a container in the given pod with the - // given container name was not found, amongst those managed by the kubelet. - ErrContainerNotFound = errors.New("no matching container") -) - -var ( - // ErrRunContainer returned when runtime failed to start any of pod's container. - ErrRunContainer = errors.New("RunContainerError") - // ErrKillContainer returned when runtime failed to kill any of pod's containers. - ErrKillContainer = errors.New("KillContainerError") - // ErrCreatePodSandbox returned when runtime failed to create a sandbox for pod. - ErrCreatePodSandbox = errors.New("CreatePodSandboxError") - // ErrConfigPodSandbox returned when runetime failed to get pod sandbox config from pod. - ErrConfigPodSandbox = errors.New("ConfigPodSandboxError") - // ErrKillPodSandbox returned when runtime failed to stop pod's sandbox. - ErrKillPodSandbox = errors.New("KillPodSandboxError") - // ErrResizePodInPlace returned when runtime failed to resize a pod. - ErrResizePodInPlace = errors.New("ResizePodInPlaceError") -) - -// SyncAction indicates different kind of actions in SyncPod() and KillPod(). Now there are only actions -// about start/kill container and setup/teardown network. -type SyncAction string - -const ( - // StartContainer action - StartContainer SyncAction = "StartContainer" - // KillContainer action - KillContainer SyncAction = "KillContainer" - // SetupNetwork action - SetupNetwork SyncAction = "SetupNetwork" - // TeardownNetwork action - TeardownNetwork SyncAction = "TeardownNetwork" - // InitContainer action - InitContainer SyncAction = "InitContainer" - // CreatePodSandbox action - CreatePodSandbox SyncAction = "CreatePodSandbox" - // ConfigPodSandbox action - ConfigPodSandbox SyncAction = "ConfigPodSandbox" - // KillPodSandbox action - KillPodSandbox SyncAction = "KillPodSandbox" - // ResizePodInPlace action is included whenever any containers in the pod are resized without restart - ResizePodInPlace SyncAction = "ResizePodInPlace" -) - -// SyncResult is the result of sync action. -type SyncResult struct { - // The associated action of the result - Action SyncAction - // The target of the action, now the target can only be: - // * Container: Target should be container name - // * Network: Target is useless now, we just set it as pod full name now - Target interface{} - // Brief error reason - Error error - // Human readable error reason - Message string -} - -// NewSyncResult generates new SyncResult with specific Action and Target -func NewSyncResult(action SyncAction, target interface{}) *SyncResult { - return &SyncResult{Action: action, Target: target} -} - -// Fail fails the SyncResult with specific error and message -func (r *SyncResult) Fail(err error, msg string) { - r.Error, r.Message = err, msg -} - -// PodSyncResult is the summary result of SyncPod() and KillPod() -type PodSyncResult struct { - // Result of different sync actions - SyncResults []*SyncResult - // Error encountered in SyncPod() and KillPod() that is not already included in SyncResults - SyncError error -} - -// AddSyncResult adds multiple SyncResult to current PodSyncResult -func (p *PodSyncResult) AddSyncResult(result ...*SyncResult) { - p.SyncResults = append(p.SyncResults, result...) -} - -// AddPodSyncResult merges a PodSyncResult to current one -func (p *PodSyncResult) AddPodSyncResult(result PodSyncResult) { - p.AddSyncResult(result.SyncResults...) - p.SyncError = result.SyncError -} - -// Fail fails the PodSyncResult with an error occurred in SyncPod() and KillPod() itself -func (p *PodSyncResult) Fail(err error) { - p.SyncError = err -} - -// Error returns an error summarizing all the errors in PodSyncResult -func (p *PodSyncResult) Error() error { - errlist := []error{} - if p.SyncError != nil { - errlist = append(errlist, fmt.Errorf("failed to SyncPod: %v", p.SyncError)) - } - for _, result := range p.SyncResults { - if result.Error != nil { - errlist = append(errlist, fmt.Errorf("failed to %q for %q with %v: %q", result.Action, result.Target, - result.Error, result.Message)) - } - } - return utilerrors.NewAggregate(errlist) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go b/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go index 526a67cdb..3b3d13705 100644 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go +++ b/vendor/k8s.io/kubernetes/pkg/kubelet/events/event.go @@ -36,6 +36,7 @@ const ( NetworkNotReady = "NetworkNotReady" ResizeDeferred = "ResizeDeferred" ResizeInfeasible = "ResizeInfeasible" + ResizeCompleted = "ResizeCompleted" ) // Image event reason list diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/api/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/api/types.go deleted file mode 100644 index 359f13e7b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/eviction/api/types.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package api - -import ( - "time" - - "k8s.io/apimachinery/pkg/api/resource" -) - -// Signal defines a signal that can trigger eviction of pods on a node. -type Signal string - -const ( - // SignalMemoryAvailable is memory available (i.e. capacity - workingSet), in bytes. - SignalMemoryAvailable Signal = "memory.available" - // SignalNodeFsAvailable is amount of storage available on filesystem that kubelet uses for volumes, daemon logs, etc. - SignalNodeFsAvailable Signal = "nodefs.available" - // SignalNodeFsInodesFree is amount of inodes available on filesystem that kubelet uses for volumes, daemon logs, etc. - SignalNodeFsInodesFree Signal = "nodefs.inodesFree" - // SignalImageFsAvailable is amount of storage available on filesystem that container runtime uses for storing images layers. - // If the container filesystem and image filesystem are not separate, - // than imagefs can store both image layers and writeable layers. - SignalImageFsAvailable Signal = "imagefs.available" - // SignalImageFsInodesFree is amount of inodes available on filesystem that container runtime uses for storing images layers. - // If the container filesystem and image filesystem are not separate, - // than imagefs can store both image layers and writeable layers. - SignalImageFsInodesFree Signal = "imagefs.inodesFree" - // SignalContainerFsAvailable is amount of storage available on filesystem that container runtime uses for container writable layers. - // In case of a single filesystem, containerfs=nodefs. - // In case of a image filesystem, containerfs=imagefs. - // We will override user settings and set to either imagefs or nodefs depending on configuration. - SignalContainerFsAvailable Signal = "containerfs.available" - // SignalContainerFsInodesFree is amount of inodes available on filesystem that container runtime uses for container writable layers. - // In case of a single filesystem, containerfs=nodefs. - // In case of a image filesystem, containerfs=imagefs. - // We will override user settings and set to either imagefs or nodefs depending on configuration. - SignalContainerFsInodesFree Signal = "containerfs.inodesFree" - // SignalAllocatableMemoryAvailable is amount of memory available for pod allocation (i.e. allocatable - workingSet (of pods), in bytes. - SignalAllocatableMemoryAvailable Signal = "allocatableMemory.available" - // SignalPIDAvailable is amount of PID available for pod allocation - SignalPIDAvailable Signal = "pid.available" -) - -// ThresholdOperator is the operator used to express a Threshold. -type ThresholdOperator string - -const ( - // OpLessThan is the operator that expresses a less than operator. - OpLessThan ThresholdOperator = "LessThan" -) - -// OpForSignal maps Signals to ThresholdOperators. -// Today, the only supported operator is "LessThan". This may change in the future, -// for example if "consumed" (as opposed to "available") type signals are added. -// In both cases the directionality of the threshold is implicit to the signal type -// (for a given signal, the decision to evict will be made when crossing the threshold -// from either above or below, never both). There is thus no reason to expose the -// operator in the Kubelet's public API. Instead, we internally map signal types to operators. -var OpForSignal = map[Signal]ThresholdOperator{ - SignalMemoryAvailable: OpLessThan, - SignalNodeFsAvailable: OpLessThan, - SignalNodeFsInodesFree: OpLessThan, - SignalImageFsAvailable: OpLessThan, - SignalImageFsInodesFree: OpLessThan, - SignalContainerFsAvailable: OpLessThan, - SignalContainerFsInodesFree: OpLessThan, - SignalAllocatableMemoryAvailable: OpLessThan, - SignalPIDAvailable: OpLessThan, -} - -// ThresholdValue is a value holder that abstracts literal versus percentage based quantity -type ThresholdValue struct { - // The following fields are exclusive. Only the topmost non-zero field is used. - - // Quantity is a quantity associated with the signal that is evaluated against the specified operator. - Quantity *resource.Quantity - // Percentage represents the usage percentage over the total resource that is evaluated against the specified operator. - Percentage float32 -} - -// Threshold defines a metric for when eviction should occur. -type Threshold struct { - // Signal defines the entity that was measured. - Signal Signal - // Operator represents a relationship of a signal to a value. - Operator ThresholdOperator - // Value is the threshold the resource is evaluated against. - Value ThresholdValue - // GracePeriod represents the amount of time that a threshold must be met before eviction is triggered. - GracePeriod time.Duration - // MinReclaim represents the minimum amount of resource to reclaim if the threshold is met. - MinReclaim *ThresholdValue -} - -// GetThresholdQuantity returns the expected quantity value for a thresholdValue -func GetThresholdQuantity(value ThresholdValue, capacity *resource.Quantity) *resource.Quantity { - if value.Quantity != nil { - res := value.Quantity.DeepCopy() - return &res - } - return resource.NewQuantity(int64(float64(capacity.Value())*float64(value.Percentage)), resource.BinarySI) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go b/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go deleted file mode 100644 index e980fd1ba..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/kuberuntime/util/util.go +++ /dev/null @@ -1,127 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - v1 "k8s.io/api/core/v1" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" - "k8s.io/klog/v2" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" -) - -// PodSandboxChanged checks whether the spec of the pod is changed and returns -// (changed, new attempt, original sandboxID if exist). -func PodSandboxChanged(pod *v1.Pod, podStatus *kubecontainer.PodStatus) (bool, uint32, string) { - if len(podStatus.SandboxStatuses) == 0 { - klog.V(2).InfoS("No sandbox for pod can be found. Need to start a new one", "pod", klog.KObj(pod)) - return true, 0, "" - } - - readySandboxCount := 0 - for _, s := range podStatus.SandboxStatuses { - if s.State == runtimeapi.PodSandboxState_SANDBOX_READY { - readySandboxCount++ - } - } - - // Needs to create a new sandbox when readySandboxCount > 1 or the ready sandbox is not the latest one. - sandboxStatus := podStatus.SandboxStatuses[0] - if readySandboxCount > 1 { - klog.V(2).InfoS("Multiple sandboxes are ready for Pod. Need to reconcile them", "pod", klog.KObj(pod)) - return true, sandboxStatus.Metadata.Attempt + 1, sandboxStatus.Id - } - if sandboxStatus.State != runtimeapi.PodSandboxState_SANDBOX_READY { - klog.V(2).InfoS("No ready sandbox for pod can be found. Need to start a new one", "pod", klog.KObj(pod)) - return true, sandboxStatus.Metadata.Attempt + 1, sandboxStatus.Id - } - - // Needs to create a new sandbox when network namespace changed. - if sandboxStatus.GetLinux().GetNamespaces().GetOptions().GetNetwork() != NetworkNamespaceForPod(pod) { - klog.V(2).InfoS("Sandbox for pod has changed. Need to start a new one", "pod", klog.KObj(pod)) - return true, sandboxStatus.Metadata.Attempt + 1, "" - } - - // Needs to create a new sandbox when the sandbox does not have an IP address. - if !kubecontainer.IsHostNetworkPod(pod) && sandboxStatus.Network != nil && sandboxStatus.Network.Ip == "" { - klog.V(2).InfoS("Sandbox for pod has no IP address. Need to start a new one", "pod", klog.KObj(pod)) - return true, sandboxStatus.Metadata.Attempt + 1, sandboxStatus.Id - } - - return false, sandboxStatus.Metadata.Attempt, sandboxStatus.Id -} - -// IpcNamespaceForPod returns the runtimeapi.NamespaceMode -// for the IPC namespace of a pod -func IpcNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { - if pod != nil && pod.Spec.HostIPC { - return runtimeapi.NamespaceMode_NODE - } - return runtimeapi.NamespaceMode_POD -} - -// NetworkNamespaceForPod returns the runtimeapi.NamespaceMode -// for the network namespace of a pod -func NetworkNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { - if pod != nil && pod.Spec.HostNetwork { - return runtimeapi.NamespaceMode_NODE - } - return runtimeapi.NamespaceMode_POD -} - -// PidNamespaceForPod returns the runtimeapi.NamespaceMode -// for the PID namespace of a pod -func PidNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode { - if pod != nil { - if pod.Spec.HostPID { - return runtimeapi.NamespaceMode_NODE - } - if pod.Spec.ShareProcessNamespace != nil && *pod.Spec.ShareProcessNamespace { - return runtimeapi.NamespaceMode_POD - } - } - // Note that PID does not default to the zero value for v1.Pod - return runtimeapi.NamespaceMode_CONTAINER -} - -// LookupRuntimeHandler is implemented by *runtimeclass.Manager. -type RuntimeHandlerResolver interface { - LookupRuntimeHandler(runtimeClassName *string) (string, error) -} - -// namespacesForPod returns the runtimeapi.NamespaceOption for a given pod. -// An empty or nil pod can be used to get the namespace defaults for v1.Pod. -func NamespacesForPod(pod *v1.Pod, runtimeHelper kubecontainer.RuntimeHelper, rcManager RuntimeHandlerResolver) (*runtimeapi.NamespaceOption, error) { - runtimeHandler := "" - if pod != nil && rcManager != nil { - var err error - runtimeHandler, err = rcManager.LookupRuntimeHandler(pod.Spec.RuntimeClassName) - if err != nil { - return nil, err - } - } - userNs, err := runtimeHelper.GetOrCreateUserNamespaceMappings(pod, runtimeHandler) - if err != nil { - return nil, err - } - - return &runtimeapi.NamespaceOption{ - Ipc: IpcNamespaceForPod(pod), - Network: NetworkNamespaceForPod(pod), - Pid: PidNamespaceForPod(pod), - UsernsOptions: userNs, - }, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go deleted file mode 100644 index d22df7409..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/admission_failure_handler_stub.go +++ /dev/null @@ -1,37 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package lifecycle - -import ( - "k8s.io/api/core/v1" -) - -// AdmissionFailureHandlerStub is an AdmissionFailureHandler that does not perform any handling of admission failure. -// It simply passes the failure on. -type AdmissionFailureHandlerStub struct{} - -var _ AdmissionFailureHandler = &AdmissionFailureHandlerStub{} - -// NewAdmissionFailureHandlerStub returns an instance of AdmissionFailureHandlerStub. -func NewAdmissionFailureHandlerStub() *AdmissionFailureHandlerStub { - return &AdmissionFailureHandlerStub{} -} - -// HandleAdmissionFailure simply passes admission rejection on, with no special handling. -func (n *AdmissionFailureHandlerStub) HandleAdmissionFailure(admitPod *v1.Pod, failureReasons []PredicateFailureReason) ([]PredicateFailureReason, error) { - return failureReasons, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go deleted file mode 100644 index 0c1dd9a1c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/doc.go +++ /dev/null @@ -1,19 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package lifecycle contains handlers for pod lifecycle events and interfaces -// to integrate with kubelet admission, synchronization, and eviction of pods. -package lifecycle diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go deleted file mode 100644 index b0c22a78d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/handlers.go +++ /dev/null @@ -1,243 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package lifecycle - -import ( - "context" - "errors" - "fmt" - "io" - "net/http" - "net/url" - "strconv" - "strings" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/client-go/tools/record" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/features" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/metrics" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" - "k8s.io/kubernetes/pkg/kubelet/util/format" - httpprobe "k8s.io/kubernetes/pkg/probe/http" - "k8s.io/kubernetes/pkg/security/apparmor" -) - -const ( - maxRespBodyLength = 10 * 1 << 10 // 10KB - - AppArmorNotAdmittedReason = "AppArmor" -) - -type handlerRunner struct { - httpDoer kubetypes.HTTPDoer - commandRunner kubecontainer.CommandRunner - containerManager podStatusProvider - eventRecorder record.EventRecorder -} - -type podStatusProvider interface { - GetPodStatus(ctx context.Context, uid types.UID, name, namespace string) (*kubecontainer.PodStatus, error) -} - -// NewHandlerRunner returns a configured lifecycle handler for a container. -func NewHandlerRunner(httpDoer kubetypes.HTTPDoer, commandRunner kubecontainer.CommandRunner, containerManager podStatusProvider, eventRecorder record.EventRecorder) kubecontainer.HandlerRunner { - return &handlerRunner{ - httpDoer: httpDoer, - commandRunner: commandRunner, - containerManager: containerManager, - eventRecorder: eventRecorder, - } -} - -func (hr *handlerRunner) Run(ctx context.Context, containerID kubecontainer.ContainerID, pod *v1.Pod, container *v1.Container, handler *v1.LifecycleHandler) (string, error) { - switch { - case handler.Exec != nil: - var msg string - // TODO(tallclair): Pass a proper timeout value. - output, err := hr.commandRunner.RunInContainer(ctx, containerID, handler.Exec.Command, 0) - if err != nil { - msg = fmt.Sprintf("Exec lifecycle hook (%v) for Container %q in Pod %q failed - error: %v, message: %q", handler.Exec.Command, container.Name, format.Pod(pod), err, string(output)) - klog.V(1).ErrorS(err, "Exec lifecycle hook for Container in Pod failed", "execCommand", handler.Exec.Command, "containerName", container.Name, "pod", klog.KObj(pod), "message", string(output)) - } - return msg, err - case handler.HTTPGet != nil: - err := hr.runHTTPHandler(ctx, pod, container, handler, hr.eventRecorder) - var msg string - if err != nil { - msg = fmt.Sprintf("HTTP lifecycle hook (%s) for Container %q in Pod %q failed - error: %v", handler.HTTPGet.Path, container.Name, format.Pod(pod), err) - klog.V(1).ErrorS(err, "HTTP lifecycle hook for Container in Pod failed", "path", handler.HTTPGet.Path, "containerName", container.Name, "pod", klog.KObj(pod)) - } - return msg, err - case handler.Sleep != nil: - err := hr.runSleepHandler(ctx, handler.Sleep.Seconds) - var msg string - if err != nil { - msg = fmt.Sprintf("Sleep lifecycle hook (%d) for Container %q in Pod %q failed - error: %v", handler.Sleep.Seconds, container.Name, format.Pod(pod), err) - klog.V(1).ErrorS(err, "Sleep lifecycle hook for Container in Pod failed", "sleepSeconds", handler.Sleep.Seconds, "containerName", container.Name, "pod", klog.KObj(pod)) - } - return msg, err - default: - err := fmt.Errorf("invalid handler: %v", handler) - msg := fmt.Sprintf("Cannot run handler: %v", err) - klog.ErrorS(err, "Cannot run handler") - return msg, err - } -} - -// resolvePort attempts to turn an IntOrString port reference into a concrete port number. -// If portReference has an int value, it is treated as a literal, and simply returns that value. -// If portReference is a string, an attempt is first made to parse it as an integer. If that fails, -// an attempt is made to find a port with the same name in the container spec. -// If a port with the same name is found, it's ContainerPort value is returned. If no matching -// port is found, an error is returned. -func resolvePort(portReference intstr.IntOrString, container *v1.Container) (int, error) { - if portReference.Type == intstr.Int { - return portReference.IntValue(), nil - } - portName := portReference.StrVal - port, err := strconv.Atoi(portName) - if err == nil { - return port, nil - } - for _, portSpec := range container.Ports { - if portSpec.Name == portName { - return int(portSpec.ContainerPort), nil - } - } - return -1, fmt.Errorf("couldn't find port: %v in %v", portReference, container) -} - -func (hr *handlerRunner) runSleepHandler(ctx context.Context, seconds int64) error { - if !utilfeature.DefaultFeatureGate.Enabled(features.PodLifecycleSleepAction) { - return nil - } - c := time.After(time.Duration(seconds) * time.Second) - select { - case <-ctx.Done(): - // unexpected termination - metrics.LifecycleHandlerSleepTerminated.Inc() - return fmt.Errorf("container terminated before sleep hook finished") - case <-c: - return nil - } -} - -func (hr *handlerRunner) runHTTPHandler(ctx context.Context, pod *v1.Pod, container *v1.Container, handler *v1.LifecycleHandler, eventRecorder record.EventRecorder) error { - host := handler.HTTPGet.Host - podIP := host - if len(host) == 0 { - status, err := hr.containerManager.GetPodStatus(ctx, pod.UID, pod.Name, pod.Namespace) - if err != nil { - klog.ErrorS(err, "Unable to get pod info, event handlers may be invalid.", "pod", klog.KObj(pod)) - return err - } - if len(status.IPs) == 0 { - return fmt.Errorf("failed to find networking container: %v", status) - } - host = status.IPs[0] - podIP = host - } - - req, err := httpprobe.NewRequestForHTTPGetAction(handler.HTTPGet, container, podIP, "lifecycle") - if err != nil { - return err - } - resp, err := hr.httpDoer.Do(req) - discardHTTPRespBody(resp) - - if isHTTPResponseError(err) { - klog.V(1).ErrorS(err, "HTTPS request to lifecycle hook got HTTP response, retrying with HTTP.", "pod", klog.KObj(pod), "host", req.URL.Host) - - req := req.Clone(context.Background()) - req.URL.Scheme = "http" - req.Header.Del("Authorization") - resp, httpErr := hr.httpDoer.Do(req) - - // clear err since the fallback succeeded - if httpErr == nil { - metrics.LifecycleHandlerHTTPFallbacks.Inc() - if eventRecorder != nil { - // report the fallback with an event - eventRecorder.Event(pod, v1.EventTypeWarning, "LifecycleHTTPFallback", fmt.Sprintf("request to HTTPS lifecycle hook %s got HTTP response, retry with HTTP succeeded", req.URL.Host)) - } - err = nil - } - discardHTTPRespBody(resp) - } - return err -} - -func discardHTTPRespBody(resp *http.Response) { - if resp == nil { - return - } - - // Ensure the response body is fully read and closed - // before we reconnect, so that we reuse the same TCP - // connection. - defer resp.Body.Close() - - if resp.ContentLength <= maxRespBodyLength { - io.Copy(io.Discard, &io.LimitedReader{R: resp.Body, N: maxRespBodyLength}) - } -} - -// NewAppArmorAdmitHandler returns a PodAdmitHandler which is used to evaluate -// if a pod can be admitted from the perspective of AppArmor. -func NewAppArmorAdmitHandler(validator apparmor.Validator) PodAdmitHandler { - return &appArmorAdmitHandler{ - Validator: validator, - } -} - -type appArmorAdmitHandler struct { - apparmor.Validator -} - -func (a *appArmorAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult { - // If the pod is already running or terminated, no need to recheck AppArmor. - if attrs.Pod.Status.Phase != v1.PodPending { - return PodAdmitResult{Admit: true} - } - - err := a.Validate(attrs.Pod) - if err == nil { - return PodAdmitResult{Admit: true} - } - return PodAdmitResult{ - Admit: false, - Reason: AppArmorNotAdmittedReason, - Message: fmt.Sprintf("Cannot enforce AppArmor: %v", err), - } -} - -func isHTTPResponseError(err error) bool { - if err == nil { - return false - } - urlErr := &url.Error{} - if !errors.As(err, &urlErr) { - return false - } - return strings.Contains(urlErr.Err.Error(), "server gave HTTP response to HTTPS client") -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go deleted file mode 100644 index 3be7adade..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/interfaces.go +++ /dev/null @@ -1,122 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package lifecycle - -import "k8s.io/api/core/v1" - -// PodAdmitAttributes is the context for a pod admission decision. -// The member fields of this struct should never be mutated. -type PodAdmitAttributes struct { - // the pod to evaluate for admission - Pod *v1.Pod - // all pods bound to the kubelet excluding the pod being evaluated - OtherPods []*v1.Pod -} - -// PodAdmitResult provides the result of a pod admission decision. -type PodAdmitResult struct { - // if true, the pod should be admitted. - Admit bool - // a brief single-word reason why the pod could not be admitted. - Reason string - // a brief message explaining why the pod could not be admitted. - Message string -} - -// PodAdmitHandler is notified during pod admission. -type PodAdmitHandler interface { - // Admit evaluates if a pod can be admitted. - Admit(attrs *PodAdmitAttributes) PodAdmitResult -} - -// PodAdmitTarget maintains a list of handlers to invoke. -type PodAdmitTarget interface { - // AddPodAdmitHandler adds the specified handler. - AddPodAdmitHandler(a PodAdmitHandler) -} - -// PodSyncLoopHandler is invoked during each sync loop iteration. -type PodSyncLoopHandler interface { - // ShouldSync returns true if the pod needs to be synced. - // This operation must return immediately as its called for each pod. - // The provided pod should never be modified. - ShouldSync(pod *v1.Pod) bool -} - -// PodSyncLoopTarget maintains a list of handlers to pod sync loop. -type PodSyncLoopTarget interface { - // AddPodSyncLoopHandler adds the specified handler. - AddPodSyncLoopHandler(a PodSyncLoopHandler) -} - -// ShouldEvictResponse provides the result of a should evict request. -type ShouldEvictResponse struct { - // if true, the pod should be evicted. - Evict bool - // a brief CamelCase reason why the pod should be evicted. - Reason string - // a brief message why the pod should be evicted. - Message string -} - -// PodSyncHandler is invoked during each sync pod operation. -type PodSyncHandler interface { - // ShouldEvict is invoked during each sync pod operation to determine - // if the pod should be evicted from the kubelet. If so, the pod status - // is updated to mark its phase as failed with the provided reason and message, - // and the pod is immediately killed. - // This operation must return immediately as its called for each sync pod. - // The provided pod should never be modified. - ShouldEvict(pod *v1.Pod) ShouldEvictResponse -} - -// PodSyncTarget maintains a list of handlers to pod sync. -type PodSyncTarget interface { - // AddPodSyncHandler adds the specified handler - AddPodSyncHandler(a PodSyncHandler) -} - -// PodLifecycleTarget groups a set of lifecycle interfaces for convenience. -type PodLifecycleTarget interface { - PodAdmitTarget - PodSyncLoopTarget - PodSyncTarget -} - -// PodAdmitHandlers maintains a list of handlers to pod admission. -type PodAdmitHandlers []PodAdmitHandler - -// AddPodAdmitHandler adds the specified observer. -func (handlers *PodAdmitHandlers) AddPodAdmitHandler(a PodAdmitHandler) { - *handlers = append(*handlers, a) -} - -// PodSyncLoopHandlers maintains a list of handlers to pod sync loop. -type PodSyncLoopHandlers []PodSyncLoopHandler - -// AddPodSyncLoopHandler adds the specified observer. -func (handlers *PodSyncLoopHandlers) AddPodSyncLoopHandler(a PodSyncLoopHandler) { - *handlers = append(*handlers, a) -} - -// PodSyncHandlers maintains a list of handlers to pod sync. -type PodSyncHandlers []PodSyncHandler - -// AddPodSyncHandler adds the specified handler. -func (handlers *PodSyncHandlers) AddPodSyncHandler(a PodSyncHandler) { - *handlers = append(*handlers, a) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go b/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go deleted file mode 100644 index a505faca6..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/lifecycle/predicate.go +++ /dev/null @@ -1,412 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package lifecycle - -import ( - "fmt" - "runtime" - - v1 "k8s.io/api/core/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/component-base/featuregate" - "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/klog/v2" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/types" - "k8s.io/kubernetes/pkg/scheduler" - schedulerframework "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration" - "k8s.io/utils/ptr" -) - -const ( - // PodOSSelectorNodeLabelDoesNotMatch is used to denote that the pod was - // rejected admission to the node because the pod's node selector - // corresponding to kubernetes.io/os label didn't match the node label. - PodOSSelectorNodeLabelDoesNotMatch = "PodOSSelectorNodeLabelDoesNotMatch" - - // PodOSNotSupported is used to denote that the pod was rejected admission - // to the node because the pod's OS field didn't match the node OS. - PodOSNotSupported = "PodOSNotSupported" - - // InvalidNodeInfo is used to denote that the pod was rejected admission - // to the node because the kubelet was unable to retrieve the node info. - InvalidNodeInfo = "InvalidNodeInfo" - - // InitContainerRestartPolicyForbidden is used to denote that the pod was - // rejected admission to the node because it uses a restart policy other - // than Always for some of its init containers. - InitContainerRestartPolicyForbidden = "InitContainerRestartPolicyForbidden" - - // SupplementalGroupsPolicyNotSupported is used to denote that the pod was - // rejected admission to the node because the node does not support - // the pod's SupplementalGroupsPolicy. - SupplementalGroupsPolicyNotSupported = "SupplementalGroupsPolicyNotSupported" - - // UnexpectedAdmissionError is used to denote that the pod was rejected - // admission to the node because of an error during admission that could not - // be categorized. - UnexpectedAdmissionError = "UnexpectedAdmissionError" - - // UnknownReason is used to denote that the pod was rejected admission to - // the node because a predicate failed for a reason that could not be - // determined. - UnknownReason = "UnknownReason" - - // UnexpectedPredicateFailureType is used to denote that the pod was - // rejected admission to the node because a predicate returned a reason - // object that was not an InsufficientResourceError or a PredicateFailureError. - UnexpectedPredicateFailureType = "UnexpectedPredicateFailureType" - - // Prefix for admission reason when kubelet rejects a pod due to insufficient - // resources available. - InsufficientResourcePrefix = "OutOf" - - // These reasons are used to denote that the pod has reject admission - // to the node because there's not enough resources to run the pod. - OutOfCPU = "OutOfcpu" - OutOfMemory = "OutOfmemory" - OutOfEphemeralStorage = "OutOfephemeral-storage" - OutOfPods = "OutOfpods" -) - -type getNodeAnyWayFuncType func() (*v1.Node, error) - -type pluginResourceUpdateFuncType func(*schedulerframework.NodeInfo, *PodAdmitAttributes) error - -// AdmissionFailureHandler is an interface which defines how to deal with a failure to admit a pod. -// This allows for the graceful handling of pod admission failure. -type AdmissionFailureHandler interface { - HandleAdmissionFailure(admitPod *v1.Pod, failureReasons []PredicateFailureReason) ([]PredicateFailureReason, error) -} - -type predicateAdmitHandler struct { - getNodeAnyWayFunc getNodeAnyWayFuncType - pluginResourceUpdateFunc pluginResourceUpdateFuncType - admissionFailureHandler AdmissionFailureHandler -} - -var _ PodAdmitHandler = &predicateAdmitHandler{} - -// NewPredicateAdmitHandler returns a PodAdmitHandler which is used to evaluates -// if a pod can be admitted from the perspective of predicates. -func NewPredicateAdmitHandler(getNodeAnyWayFunc getNodeAnyWayFuncType, admissionFailureHandler AdmissionFailureHandler, pluginResourceUpdateFunc pluginResourceUpdateFuncType) PodAdmitHandler { - return &predicateAdmitHandler{ - getNodeAnyWayFunc, - pluginResourceUpdateFunc, - admissionFailureHandler, - } -} - -func (w *predicateAdmitHandler) Admit(attrs *PodAdmitAttributes) PodAdmitResult { - node, err := w.getNodeAnyWayFunc() - if err != nil { - klog.ErrorS(err, "Cannot get Node info") - return PodAdmitResult{ - Admit: false, - Reason: InvalidNodeInfo, - Message: "Kubelet cannot get node info.", - } - } - admitPod := attrs.Pod - - // perform the checks that preemption will not help first to avoid meaningless pod eviction - if rejectPodAdmissionBasedOnOSSelector(admitPod, node) { - return PodAdmitResult{ - Admit: false, - Reason: PodOSSelectorNodeLabelDoesNotMatch, - Message: "Failed to admit pod as the `kubernetes.io/os` label doesn't match node label", - } - } - if rejectPodAdmissionBasedOnOSField(admitPod) { - return PodAdmitResult{ - Admit: false, - Reason: PodOSNotSupported, - Message: "Failed to admit pod as the OS field doesn't match node OS", - } - } - - if rejectPodAdmissionBasedOnSupplementalGroupsPolicy(admitPod, node) { - message := fmt.Sprintf("SupplementalGroupsPolicy=%s is not supported in this node", v1.SupplementalGroupsPolicyStrict) - klog.InfoS("Failed to admit pod", "pod", klog.KObj(admitPod), "message", message) - return PodAdmitResult{ - Admit: false, - Reason: SupplementalGroupsPolicyNotSupported, - Message: message, - } - } - - pods := attrs.OtherPods - nodeInfo := schedulerframework.NewNodeInfo(pods...) - nodeInfo.SetNode(node) - - // ensure the node has enough plugin resources for that required in pods - if err = w.pluginResourceUpdateFunc(nodeInfo, attrs); err != nil { - message := fmt.Sprintf("Update plugin resources failed due to %v, which is unexpected.", err) - klog.InfoS("Failed to admit pod", "pod", klog.KObj(admitPod), "message", message) - return PodAdmitResult{ - Admit: false, - Reason: UnexpectedAdmissionError, - Message: message, - } - } - - // Remove the requests of the extended resources that are missing in the - // node info. This is required to support cluster-level resources, which - // are extended resources unknown to nodes. - // - // Caveat: If a pod was manually bound to a node (e.g., static pod) where a - // node-level extended resource it requires is not found, then kubelet will - // not fail admission while it should. This issue will be addressed with - // the Resource Class API in the future. - podWithoutMissingExtendedResources := removeMissingExtendedResources(admitPod, nodeInfo) - - reasons := generalFilter(podWithoutMissingExtendedResources, nodeInfo) - fit := len(reasons) == 0 - if !fit { - reasons, err = w.admissionFailureHandler.HandleAdmissionFailure(admitPod, reasons) - fit = len(reasons) == 0 && err == nil - if err != nil { - message := fmt.Sprintf("Unexpected error while attempting to recover from admission failure: %v", err) - klog.InfoS("Failed to admit pod, unexpected error while attempting to recover from admission failure", "pod", klog.KObj(admitPod), "err", err) - return PodAdmitResult{ - Admit: fit, - Reason: UnexpectedAdmissionError, - Message: message, - } - } - } - if !fit { - var reason string - var message string - if len(reasons) == 0 { - message = fmt.Sprint("GeneralPredicates failed due to unknown reason, which is unexpected.") - klog.InfoS("Failed to admit pod: GeneralPredicates failed due to unknown reason, which is unexpected", "pod", klog.KObj(admitPod)) - return PodAdmitResult{ - Admit: fit, - Reason: UnknownReason, - Message: message, - } - } - // If there are failed predicates, we only return the first one as a reason. - r := reasons[0] - switch re := r.(type) { - case *PredicateFailureError: - reason = re.PredicateName - message = re.Error() - klog.V(2).InfoS("Predicate failed on Pod", "pod", klog.KObj(admitPod), "err", message) - case *InsufficientResourceError: - switch re.ResourceName { - case v1.ResourceCPU: - reason = OutOfCPU - case v1.ResourceMemory: - reason = OutOfMemory - case v1.ResourceEphemeralStorage: - reason = OutOfEphemeralStorage - case v1.ResourcePods: - reason = OutOfPods - default: - reason = fmt.Sprintf("%s%s", InsufficientResourcePrefix, re.ResourceName) - } - message = re.Error() - klog.V(2).InfoS("Predicate failed on Pod", "pod", klog.KObj(admitPod), "err", message) - default: - reason = UnexpectedPredicateFailureType - message = fmt.Sprintf("GeneralPredicates failed due to %v, which is unexpected.", r) - klog.InfoS("Failed to admit pod", "pod", klog.KObj(admitPod), "err", message) - } - return PodAdmitResult{ - Admit: fit, - Reason: reason, - Message: message, - } - } - return PodAdmitResult{ - Admit: true, - } -} - -// rejectPodAdmissionBasedOnOSSelector rejects pod if it's nodeSelector doesn't match -// We expect the kubelet status reconcile which happens every 10sec to update the node labels if there is a mismatch. -func rejectPodAdmissionBasedOnOSSelector(pod *v1.Pod, node *v1.Node) bool { - labels := node.Labels - osName, osLabelExists := labels[v1.LabelOSStable] - if !osLabelExists || osName != runtime.GOOS { - if len(labels) == 0 { - labels = make(map[string]string) - } - labels[v1.LabelOSStable] = runtime.GOOS - } - podLabelSelector, podOSLabelExists := pod.Labels[v1.LabelOSStable] - if !podOSLabelExists { - // If the labelselector didn't exist, let's keep the current behavior as is - return false - } else if podOSLabelExists && podLabelSelector != labels[v1.LabelOSStable] { - return true - } - return false -} - -// rejectPodAdmissionBasedOnOSField rejects pods if their OS field doesn't match runtime.GOOS. -// TODO: Relax this restriction when we start supporting LCOW in kubernetes where podOS may not match -// node's OS. -func rejectPodAdmissionBasedOnOSField(pod *v1.Pod) bool { - if pod.Spec.OS == nil { - return false - } - // If the pod OS doesn't match runtime.GOOS return false - return string(pod.Spec.OS.Name) != runtime.GOOS -} - -// rejectPodAdmissionBasedOnSupplementalGroupsPolicy rejects pod only if -// - the feature is beta or above, and SupplementalPolicy=Strict is set in the pod -// - but, the node does not support the feature -// -// Note: During the feature is alpha or before(not yet released) in emulated version, -// it should admit for backward compatibility -func rejectPodAdmissionBasedOnSupplementalGroupsPolicy(pod *v1.Pod, node *v1.Node) bool { - admit, reject := false, true // just for readability - - inUse := (pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SupplementalGroupsPolicy != nil) - if !inUse { - return admit - } - - isBetaOrAbove := false - if featureSpec, ok := utilfeature.DefaultMutableFeatureGate.GetAll()[features.SupplementalGroupsPolicy]; ok { - isBetaOrAbove = (featureSpec.PreRelease == featuregate.Beta) || (featureSpec.PreRelease == featuregate.GA) - } - - if !isBetaOrAbove { - return admit - } - - featureSupportedOnNode := ptr.Deref( - ptr.Deref(node.Status.Features, v1.NodeFeatures{SupplementalGroupsPolicy: ptr.To(false)}).SupplementalGroupsPolicy, - false, - ) - effectivePolicy := ptr.Deref( - pod.Spec.SecurityContext.SupplementalGroupsPolicy, - v1.SupplementalGroupsPolicyMerge, - ) - - if effectivePolicy == v1.SupplementalGroupsPolicyStrict && !featureSupportedOnNode { - return reject - } - - return admit -} - -func removeMissingExtendedResources(pod *v1.Pod, nodeInfo *schedulerframework.NodeInfo) *v1.Pod { - filterExtendedResources := func(containers []v1.Container) { - for i, c := range containers { - // We only handle requests in Requests but not Limits because the - // PodFitsResources predicate, to which the result pod will be passed, - // does not use Limits. - filteredResources := make(v1.ResourceList) - for rName, rQuant := range c.Resources.Requests { - if v1helper.IsExtendedResourceName(rName) { - if _, found := nodeInfo.Allocatable.ScalarResources[rName]; !found { - continue - } - } - filteredResources[rName] = rQuant - } - containers[i].Resources.Requests = filteredResources - } - } - podCopy := pod.DeepCopy() - filterExtendedResources(podCopy.Spec.Containers) - filterExtendedResources(podCopy.Spec.InitContainers) - return podCopy -} - -// InsufficientResourceError is an error type that indicates what kind of resource limit is -// hit and caused the unfitting failure. -type InsufficientResourceError struct { - ResourceName v1.ResourceName - Requested int64 - Used int64 - Capacity int64 -} - -func (e *InsufficientResourceError) Error() string { - return fmt.Sprintf("Node didn't have enough resource: %s, requested: %d, used: %d, capacity: %d", - e.ResourceName, e.Requested, e.Used, e.Capacity) -} - -// PredicateFailureReason interface represents the failure reason of a predicate. -type PredicateFailureReason interface { - GetReason() string -} - -// GetReason returns the reason of the InsufficientResourceError. -func (e *InsufficientResourceError) GetReason() string { - return fmt.Sprintf("Insufficient %v", e.ResourceName) -} - -// GetInsufficientAmount returns the amount of the insufficient resource of the error. -func (e *InsufficientResourceError) GetInsufficientAmount() int64 { - return e.Requested - (e.Capacity - e.Used) -} - -// PredicateFailureError describes a failure error of predicate. -type PredicateFailureError struct { - PredicateName string - PredicateDesc string -} - -func (e *PredicateFailureError) Error() string { - return fmt.Sprintf("Predicate %s failed: %s", e.PredicateName, e.PredicateDesc) -} - -// GetReason returns the reason of the PredicateFailureError. -func (e *PredicateFailureError) GetReason() string { - return e.PredicateDesc -} - -// generalFilter checks a group of filterings that the kubelet cares about. -func generalFilter(pod *v1.Pod, nodeInfo *schedulerframework.NodeInfo) []PredicateFailureReason { - admissionResults := scheduler.AdmissionCheck(pod, nodeInfo, true) - var reasons []PredicateFailureReason - for _, r := range admissionResults { - if r.InsufficientResource != nil { - reasons = append(reasons, &InsufficientResourceError{ - ResourceName: r.InsufficientResource.ResourceName, - Requested: r.InsufficientResource.Requested, - Used: r.InsufficientResource.Used, - Capacity: r.InsufficientResource.Capacity, - }) - } else { - reasons = append(reasons, &PredicateFailureError{r.Name, r.Reason}) - } - } - - // Check taint/toleration except for static pods - if !types.IsStaticPod(pod) { - _, isUntolerated := corev1.FindMatchingUntoleratedTaint(nodeInfo.Node().Spec.Taints, pod.Spec.Tolerations, func(t *v1.Taint) bool { - // Kubelet is only interested in the NoExecute taint. - return t.Effect == v1.TaintEffectNoExecute - }) - if isUntolerated { - reasons = append(reasons, &PredicateFailureError{tainttoleration.Name, tainttoleration.ErrReasonNotMatch}) - } - } - - return reasons -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/OWNERS b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/OWNERS deleted file mode 100644 index 4971e7564..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/OWNERS +++ /dev/null @@ -1,3 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners -approvers: - - dashpole diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go deleted file mode 100644 index 7a04387ab..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/metrics/metrics.go +++ /dev/null @@ -1,1209 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package metrics - -import ( - "sync" - "time" - - "k8s.io/component-base/metrics" - "k8s.io/component-base/metrics/legacyregistry" - - "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" -) - -// This const block defines the metric names for the kubelet metrics. -const ( - FirstNetworkPodStartSLIDurationKey = "first_network_pod_start_sli_duration_seconds" - KubeletSubsystem = "kubelet" - DRASubsystem = "dra" - NodeNameKey = "node_name" - NodeLabelKey = "node" - NodeStartupPreKubeletKey = "node_startup_pre_kubelet_duration_seconds" - NodeStartupPreRegistrationKey = "node_startup_pre_registration_duration_seconds" - NodeStartupRegistrationKey = "node_startup_registration_duration_seconds" - NodeStartupPostRegistrationKey = "node_startup_post_registration_duration_seconds" - NodeStartupKey = "node_startup_duration_seconds" - PodWorkerDurationKey = "pod_worker_duration_seconds" - PodStartDurationKey = "pod_start_duration_seconds" - PodStartSLIDurationKey = "pod_start_sli_duration_seconds" - PodStartTotalDurationKey = "pod_start_total_duration_seconds" - CgroupManagerOperationsKey = "cgroup_manager_duration_seconds" - PodWorkerStartDurationKey = "pod_worker_start_duration_seconds" - PodStatusSyncDurationKey = "pod_status_sync_duration_seconds" - PLEGRelistDurationKey = "pleg_relist_duration_seconds" - PLEGDiscardEventsKey = "pleg_discard_events" - PLEGRelistIntervalKey = "pleg_relist_interval_seconds" - PLEGLastSeenKey = "pleg_last_seen_seconds" - EventedPLEGConnErrKey = "evented_pleg_connection_error_count" - EventedPLEGConnKey = "evented_pleg_connection_success_count" - EventedPLEGConnLatencyKey = "evented_pleg_connection_latency_seconds" - EvictionsKey = "evictions" - EvictionStatsAgeKey = "eviction_stats_age_seconds" - PreemptionsKey = "preemptions" - VolumeStatsCapacityBytesKey = "volume_stats_capacity_bytes" - VolumeStatsAvailableBytesKey = "volume_stats_available_bytes" - VolumeStatsUsedBytesKey = "volume_stats_used_bytes" - VolumeStatsInodesKey = "volume_stats_inodes" - VolumeStatsInodesFreeKey = "volume_stats_inodes_free" - VolumeStatsInodesUsedKey = "volume_stats_inodes_used" - VolumeStatsHealthStatusAbnormalKey = "volume_stats_health_status_abnormal" - RunningPodsKey = "running_pods" - RunningContainersKey = "running_containers" - DesiredPodCountKey = "desired_pods" - ActivePodCountKey = "active_pods" - MirrorPodCountKey = "mirror_pods" - WorkingPodCountKey = "working_pods" - OrphanedRuntimePodTotalKey = "orphaned_runtime_pods_total" - RestartedPodTotalKey = "restarted_pods_total" - ImagePullDurationKey = "image_pull_duration_seconds" - CgroupVersionKey = "cgroup_version" - - // Metrics keys of remote runtime operations - RuntimeOperationsKey = "runtime_operations_total" - RuntimeOperationsDurationKey = "runtime_operations_duration_seconds" - RuntimeOperationsErrorsKey = "runtime_operations_errors_total" - // Metrics keys of device plugin operations - DevicePluginRegistrationCountKey = "device_plugin_registration_total" - DevicePluginAllocationDurationKey = "device_plugin_alloc_duration_seconds" - // Metrics keys of pod resources operations - PodResourcesEndpointRequestsTotalKey = "pod_resources_endpoint_requests_total" - PodResourcesEndpointRequestsListKey = "pod_resources_endpoint_requests_list" - PodResourcesEndpointRequestsGetAllocatableKey = "pod_resources_endpoint_requests_get_allocatable" - PodResourcesEndpointErrorsListKey = "pod_resources_endpoint_errors_list" - PodResourcesEndpointErrorsGetAllocatableKey = "pod_resources_endpoint_errors_get_allocatable" - PodResourcesEndpointRequestsGetKey = "pod_resources_endpoint_requests_get" - PodResourcesEndpointErrorsGetKey = "pod_resources_endpoint_errors_get" - - // Metrics keys for RuntimeClass - RunPodSandboxDurationKey = "run_podsandbox_duration_seconds" - RunPodSandboxErrorsKey = "run_podsandbox_errors_total" - - // Metrics to keep track of total number of Pods and Containers started - StartedPodsTotalKey = "started_pods_total" - StartedPodsErrorsTotalKey = "started_pods_errors_total" - StartedContainersTotalKey = "started_containers_total" - StartedContainersErrorsTotalKey = "started_containers_errors_total" - - // Metrics to track HostProcess container usage by this kubelet - StartedHostProcessContainersTotalKey = "started_host_process_containers_total" - StartedHostProcessContainersErrorsTotalKey = "started_host_process_containers_errors_total" - - // Metrics to track ephemeral container usage by this kubelet - ManagedEphemeralContainersKey = "managed_ephemeral_containers" - - // Metrics to track the CPU manager behavior - CPUManagerPinningRequestsTotalKey = "cpu_manager_pinning_requests_total" - CPUManagerPinningErrorsTotalKey = "cpu_manager_pinning_errors_total" - CPUManagerSharedPoolSizeMilliCoresKey = "cpu_manager_shared_pool_size_millicores" - CPUManagerExclusiveCPUsAllocationCountKey = "cpu_manager_exclusive_cpu_allocation_count" - CPUManagerAllocationPerNUMAKey = "cpu_manager_allocation_per_numa" - - // Metrics to track the Memory manager behavior - MemoryManagerPinningRequestsTotalKey = "memory_manager_pinning_requests_total" - MemoryManagerPinningErrorsTotalKey = "memory_manager_pinning_errors_total" - - // Metrics to track the Topology manager behavior - TopologyManagerAdmissionRequestsTotalKey = "topology_manager_admission_requests_total" - TopologyManagerAdmissionErrorsTotalKey = "topology_manager_admission_errors_total" - TopologyManagerAdmissionDurationKey = "topology_manager_admission_duration_ms" - - // Metrics to track orphan pod cleanup - orphanPodCleanedVolumesKey = "orphan_pod_cleaned_volumes" - orphanPodCleanedVolumesErrorsKey = "orphan_pod_cleaned_volumes_errors" - - // Metric for tracking garbage collected images - ImageGarbageCollectedTotalKey = "image_garbage_collected_total" - - // Metric for tracking aligment of compute resources - ContainerAlignedComputeResourcesNameKey = "container_aligned_compute_resources_count" - ContainerAlignedComputeResourcesFailureNameKey = "container_aligned_compute_resources_failure_count" - ContainerAlignedComputeResourcesScopeLabelKey = "scope" - ContainerAlignedComputeResourcesBoundaryLabelKey = "boundary" - - // Metric keys for DRA operations - DRAOperationsDurationKey = "operations_duration_seconds" - DRAGRPCOperationsDurationKey = "grpc_operations_duration_seconds" - - // Values used in metric labels - Container = "container" - InitContainer = "init_container" - EphemeralContainer = "ephemeral_container" - - AlignScopePod = "pod" - AlignScopeContainer = "container" - - AlignedPhysicalCPU = "physical_cpu" - AlignedNUMANode = "numa_node" - AlignedUncoreCache = "uncore_cache" - - // Metrics to track kubelet admission rejections. - AdmissionRejectionsTotalKey = "admission_rejections_total" - - // Image Volume metrics - ImageVolumeRequestedTotalKey = "image_volume_requested_total" - ImageVolumeMountedSucceedTotalKey = "image_volume_mounted_succeed_total" - ImageVolumeMountedErrorsTotalKey = "image_volume_mounted_errors_total" -) - -type imageSizeBucket struct { - lowerBoundInBytes uint64 - label string -} - -var ( - podStartupDurationBuckets = []float64{0.5, 1, 2, 3, 4, 5, 6, 8, 10, 20, 30, 45, 60, 120, 180, 240, 300, 360, 480, 600, 900, 1200, 1800, 2700, 3600} - imagePullDurationBuckets = []float64{1, 5, 10, 20, 30, 60, 120, 180, 240, 300, 360, 480, 600, 900, 1200, 1800, 2700, 3600} - // imageSizeBuckets has the labels to be associated with image_pull_duration_seconds metric. For example, if the size of - // an image pulled is between 1GB and 5GB, the label will be "1GB-5GB". - imageSizeBuckets = []imageSizeBucket{ - {0, "0-10MB"}, - {10 * 1024 * 1024, "10MB-100MB"}, - {100 * 1024 * 1024, "100MB-500MB"}, - {500 * 1024 * 1024, "500MB-1GB"}, - {1 * 1024 * 1024 * 1024, "1GB-5GB"}, - {5 * 1024 * 1024 * 1024, "5GB-10GB"}, - {10 * 1024 * 1024 * 1024, "10GB-20GB"}, - {20 * 1024 * 1024 * 1024, "20GB-30GB"}, - {30 * 1024 * 1024 * 1024, "30GB-40GB"}, - {40 * 1024 * 1024 * 1024, "40GB-60GB"}, - {60 * 1024 * 1024 * 1024, "60GB-100GB"}, - {100 * 1024 * 1024 * 1024, "GT100GB"}, - } - // DRADurationBuckets is the bucket boundaries for DRA operation duration metrics - // DRAOperationsDuration and DRAGRPCOperationsDuration defined below in this file. - // The buckets max value 40 is based on the 45sec max gRPC timeout value defined - // for the DRA gRPC calls in the pkg/kubelet/cm/dra/plugin/registration.go - DRADurationBuckets = metrics.ExponentialBucketsRange(.1, 40, 15) -) - -var ( - // NodeName is a Gauge that tracks the ode's name. The count is always 1. - NodeName = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: NodeNameKey, - Help: "The node's name. The count is always 1.", - StabilityLevel: metrics.ALPHA, - }, - []string{NodeLabelKey}, - ) - // ContainersPerPodCount is a Histogram that tracks the number of containers per pod. - ContainersPerPodCount = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: "containers_per_pod_count", - Help: "The number of containers per pod.", - Buckets: metrics.ExponentialBuckets(1, 2, 5), - StabilityLevel: metrics.ALPHA, - }, - ) - // PodWorkerDuration is a Histogram that tracks the duration (in seconds) in takes to sync a single pod. - // Broken down by the operation type. - PodWorkerDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PodWorkerDurationKey, - Help: "Duration in seconds to sync a single pod. Broken down by operation type: create, update, or sync", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"operation_type"}, - ) - // PodStartDuration is a Histogram that tracks the duration (in seconds) it takes for a single pod to run since it's - // first time seen by kubelet. - PodStartDuration = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PodStartDurationKey, - Help: "Duration in seconds from kubelet seeing a pod for the first time to the pod starting to run", - Buckets: podStartupDurationBuckets, - StabilityLevel: metrics.ALPHA, - }, - ) - // PodStartSLIDuration is a Histogram that tracks the duration (in seconds) it takes for a single pod to run, - // excluding the time for image pulling. This metric should reflect the "Pod startup latency SLI" definition - // ref: https://github.com/kubernetes/community/blob/master/sig-scalability/slos/pod_startup_latency.md - // - // The histogram bucket boundaries for pod startup latency metrics, measured in seconds. These are hand-picked - // so as to be roughly exponential but still round numbers in everyday units. This is to minimise the number - // of buckets while allowing accurate measurement of thresholds which might be used in SLOs - // e.g. x% of pods start up within 30 seconds, or 15 minutes, etc. - PodStartSLIDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PodStartSLIDurationKey, - Help: "Duration in seconds to start a pod, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch", - Buckets: podStartupDurationBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{}, - ) - - // PodStartTotalDuration is a Histogram that tracks the duration (in seconds) it takes for a single pod to run - // since creation, including the time for image pulling. - // - // The histogram bucket boundaries for pod startup latency metrics, measured in seconds. These are hand-picked - // so as to be roughly exponential but still round numbers in everyday units. This is to minimise the number - // of buckets while allowing accurate measurement of thresholds which might be used in SLOs - // e.g. x% of pods start up within 30 seconds, or 15 minutes, etc. - PodStartTotalDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PodStartTotalDurationKey, - Help: "Duration in seconds to start a pod since creation, including time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch", - Buckets: podStartupDurationBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{}, - ) - - // FirstNetworkPodStartSLIDuration is a gauge that tracks the duration (in seconds) it takes for the first network pod to run, - // excluding the time for image pulling. This is an internal and temporary metric required because of the existing limitations of the - // existing networking subsystem and CRI/CNI implementations that will be solved by https://github.com/containernetworking/cni/issues/859 - // The metric represents the latency observed by an user to run workloads in a new node. - // ref: https://github.com/kubernetes/community/blob/master/sig-scalability/slos/pod_startup_latency.md - FirstNetworkPodStartSLIDuration = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: FirstNetworkPodStartSLIDurationKey, - Help: "Duration in seconds to start the first network pod, excluding time to pull images and run init containers, measured from pod creation timestamp to when all its containers are reported as started and observed via watch", - StabilityLevel: metrics.INTERNAL, - }, - ) - - // CgroupManagerDuration is a Histogram that tracks the duration (in seconds) it takes for cgroup manager operations to complete. - // Broken down by method. - CgroupManagerDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: CgroupManagerOperationsKey, - Help: "Duration in seconds for cgroup manager operations. Broken down by method.", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"operation_type"}, - ) - // PodWorkerStartDuration is a Histogram that tracks the duration (in seconds) it takes from kubelet seeing a pod to starting a worker. - PodWorkerStartDuration = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PodWorkerStartDurationKey, - Help: "Duration in seconds from kubelet seeing a pod to starting a worker.", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - ) - // PodStatusSyncDuration is a Histogram that tracks the duration (in seconds) in takes from the time a pod - // status is generated to the time it is synced with the apiserver. If multiple status changes are generated - // on a pod before it is written to the API, the latency is from the first update to the last event. - PodStatusSyncDuration = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PodStatusSyncDurationKey, - Help: "Duration in seconds to sync a pod status update. Measures time from detection of a change to pod status until the API is successfully updated for that pod, even if multiple intevening changes to pod status occur.", - Buckets: []float64{0.010, 0.050, 0.100, 0.500, 1, 5, 10, 20, 30, 45, 60}, - StabilityLevel: metrics.ALPHA, - }, - ) - // PLEGRelistDuration is a Histogram that tracks the duration (in seconds) it takes for relisting pods in the Kubelet's - // Pod Lifecycle Event Generator (PLEG). - PLEGRelistDuration = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PLEGRelistDurationKey, - Help: "Duration in seconds for relisting pods in PLEG.", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - ) - // PLEGDiscardEvents is a Counter that tracks the number of discarding events in the Kubelet's Pod Lifecycle Event Generator (PLEG). - PLEGDiscardEvents = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PLEGDiscardEventsKey, - Help: "The number of discard events in PLEG.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // PLEGRelistInterval is a Histogram that tracks the intervals (in seconds) between relisting in the Kubelet's - // Pod Lifecycle Event Generator (PLEG). - PLEGRelistInterval = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: PLEGRelistIntervalKey, - Help: "Interval in seconds between relisting in PLEG.", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - ) - // PLEGLastSeen is a Gauge giving the Unix timestamp when the Kubelet's - // Pod Lifecycle Event Generator (PLEG) was last seen active. - PLEGLastSeen = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: PLEGLastSeenKey, - Help: "Timestamp in seconds when PLEG was last seen active.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // EventedPLEGConnErr is a Counter that tracks the number of errors encountered during - // the establishment of streaming connection with the CRI runtime. - EventedPLEGConnErr = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: EventedPLEGConnErrKey, - Help: "The number of errors encountered during the establishment of streaming connection with the CRI runtime.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // EventedPLEGConn is a Counter that tracks the number of times a streaming client - // was obtained to receive CRI Events. - EventedPLEGConn = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: EventedPLEGConnKey, - Help: "The number of times a streaming client was obtained to receive CRI Events.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // EventedPLEGConnLatency is a Histogram that tracks the latency of streaming connection - // with the CRI runtime, measured in seconds. - EventedPLEGConnLatency = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: EventedPLEGConnLatencyKey, - Help: "The latency of streaming connection with the CRI runtime, measured in seconds.", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - ) - - // RuntimeOperations is a Counter that tracks the cumulative number of remote runtime operations. - // Broken down by operation type. - RuntimeOperations = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: RuntimeOperationsKey, - Help: "Cumulative number of runtime operations by operation type.", - StabilityLevel: metrics.ALPHA, - }, - []string{"operation_type"}, - ) - // RuntimeOperationsDuration is a Histogram that tracks the duration (in seconds) for remote runtime operations to complete. - // Broken down by operation type. - RuntimeOperationsDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: RuntimeOperationsDurationKey, - Help: "Duration in seconds of runtime operations. Broken down by operation type.", - Buckets: metrics.ExponentialBuckets(.005, 2.5, 14), - StabilityLevel: metrics.ALPHA, - }, - []string{"operation_type"}, - ) - // RuntimeOperationsErrors is a Counter that tracks the cumulative number of remote runtime operations errors. - // Broken down by operation type. - RuntimeOperationsErrors = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: RuntimeOperationsErrorsKey, - Help: "Cumulative number of runtime operation errors by operation type.", - StabilityLevel: metrics.ALPHA, - }, - []string{"operation_type"}, - ) - // Evictions is a Counter that tracks the cumulative number of pod evictions initiated by the kubelet. - // Broken down by eviction signal. - Evictions = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: EvictionsKey, - Help: "Cumulative number of pod evictions by eviction signal", - StabilityLevel: metrics.ALPHA, - }, - []string{"eviction_signal"}, - ) - // EvictionStatsAge is a Histogram that tracks the time (in seconds) between when stats are collected and when a pod is evicted - // based on those stats. Broken down by eviction signal. - EvictionStatsAge = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: EvictionStatsAgeKey, - Help: "Time between when stats are collected, and when pod is evicted based on those stats by eviction signal", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"eviction_signal"}, - ) - // Preemptions is a Counter that tracks the cumulative number of pod preemptions initiated by the kubelet. - // Broken down by preemption signal. A preemption is only recorded for one resource, the sum of all signals - // is the number of preemptions on the given node. - Preemptions = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PreemptionsKey, - Help: "Cumulative number of pod preemptions by preemption resource", - StabilityLevel: metrics.ALPHA, - }, - []string{"preemption_signal"}, - ) - // DevicePluginRegistrationCount is a Counter that tracks the cumulative number of device plugin registrations. - // Broken down by resource name. - DevicePluginRegistrationCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: DevicePluginRegistrationCountKey, - Help: "Cumulative number of device plugin registrations. Broken down by resource name.", - StabilityLevel: metrics.ALPHA, - }, - []string{"resource_name"}, - ) - // DevicePluginAllocationDuration is a Histogram that tracks the duration (in seconds) to serve a device plugin allocation request. - // Broken down by resource name. - DevicePluginAllocationDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: DevicePluginAllocationDurationKey, - Help: "Duration in seconds to serve a device plugin Allocation request. Broken down by resource name.", - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"resource_name"}, - ) - - // PodResourcesEndpointRequestsTotalCount is a Counter that tracks the cumulative number of requests to the PodResource endpoints. - // Broken down by server API version. - PodResourcesEndpointRequestsTotalCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PodResourcesEndpointRequestsTotalKey, - Help: "Cumulative number of requests to the PodResource endpoint. Broken down by server api version.", - StabilityLevel: metrics.ALPHA, - }, - []string{"server_api_version"}, - ) - - // PodResourcesEndpointRequestsListCount is a Counter that tracks the number of requests to the PodResource List() endpoint. - // Broken down by server API version. - PodResourcesEndpointRequestsListCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PodResourcesEndpointRequestsListKey, - Help: "Number of requests to the PodResource List endpoint. Broken down by server api version.", - StabilityLevel: metrics.ALPHA, - }, - []string{"server_api_version"}, - ) - - // PodResourcesEndpointRequestsGetAllocatableCount is a Counter that tracks the number of requests to the PodResource GetAllocatableResources() endpoint. - // Broken down by server API version. - PodResourcesEndpointRequestsGetAllocatableCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PodResourcesEndpointRequestsGetAllocatableKey, - Help: "Number of requests to the PodResource GetAllocatableResources endpoint. Broken down by server api version.", - StabilityLevel: metrics.ALPHA, - }, - []string{"server_api_version"}, - ) - - // PodResourcesEndpointErrorsListCount is a Counter that tracks the number of errors returned by he PodResource List() endpoint. - // Broken down by server API version. - PodResourcesEndpointErrorsListCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PodResourcesEndpointErrorsListKey, - Help: "Number of requests to the PodResource List endpoint which returned error. Broken down by server api version.", - StabilityLevel: metrics.ALPHA, - }, - []string{"server_api_version"}, - ) - - // PodResourcesEndpointErrorsGetAllocatableCount is a Counter that tracks the number of errors returned by the PodResource GetAllocatableResources() endpoint. - // Broken down by server API version. - PodResourcesEndpointErrorsGetAllocatableCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PodResourcesEndpointErrorsGetAllocatableKey, - Help: "Number of requests to the PodResource GetAllocatableResources endpoint which returned error. Broken down by server api version.", - StabilityLevel: metrics.ALPHA, - }, - []string{"server_api_version"}, - ) - - // PodResourcesEndpointRequestsGetCount is a Counter that tracks the number of requests to the PodResource Get() endpoint. - // Broken down by server API version. - PodResourcesEndpointRequestsGetCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PodResourcesEndpointRequestsGetKey, - Help: "Number of requests to the PodResource Get endpoint. Broken down by server api version.", - StabilityLevel: metrics.ALPHA, - }, - []string{"server_api_version"}, - ) - - // PodResourcesEndpointErrorsGetCount is a Counter that tracks the number of errors returned by he PodResource List() endpoint. - // Broken down by server API version. - PodResourcesEndpointErrorsGetCount = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: PodResourcesEndpointErrorsGetKey, - Help: "Number of requests to the PodResource Get endpoint which returned error. Broken down by server api version.", - StabilityLevel: metrics.ALPHA, - }, - []string{"server_api_version"}, - ) - - // RunPodSandboxDuration is a Histogram that tracks the duration (in seconds) it takes to run Pod Sandbox operations. - // Broken down by RuntimeClass.Handler. - RunPodSandboxDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: RunPodSandboxDurationKey, - Help: "Duration in seconds of the run_podsandbox operations. Broken down by RuntimeClass.Handler.", - // Use DefBuckets for now, will customize the buckets if necessary. - Buckets: metrics.DefBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"runtime_handler"}, - ) - // RunPodSandboxErrors is a Counter that tracks the cumulative number of Pod Sandbox operations errors. - // Broken down by RuntimeClass.Handler. - RunPodSandboxErrors = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: RunPodSandboxErrorsKey, - Help: "Cumulative number of the run_podsandbox operation errors by RuntimeClass.Handler.", - StabilityLevel: metrics.ALPHA, - }, - []string{"runtime_handler"}, - ) - - // RunningPodCount is a gauge that tracks the number of Pods currently with a running sandbox - // It is used to expose the kubelet internal state: how many pods have running containers in the container runtime, and mainly for debugging purpose. - RunningPodCount = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: RunningPodsKey, - Help: "Number of pods that have a running pod sandbox", - StabilityLevel: metrics.ALPHA, - }, - ) - // RunningContainerCount is a gauge that tracks the number of containers currently running - RunningContainerCount = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: RunningContainersKey, - Help: "Number of containers currently running", - StabilityLevel: metrics.ALPHA, - }, - []string{"container_state"}, - ) - // DesiredPodCount tracks the count of pods the Kubelet thinks it should be running - DesiredPodCount = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: DesiredPodCountKey, - Help: "The number of pods the kubelet is being instructed to run. static is true if the pod is not from the apiserver.", - StabilityLevel: metrics.ALPHA, - }, - []string{"static"}, - ) - // ActivePodCount tracks the count of pods the Kubelet considers as active when deciding to admit a new pod - ActivePodCount = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: ActivePodCountKey, - Help: "The number of pods the kubelet considers active and which are being considered when admitting new pods. static is true if the pod is not from the apiserver.", - StabilityLevel: metrics.ALPHA, - }, - []string{"static"}, - ) - // MirrorPodCount tracks the number of mirror pods the Kubelet should have created for static pods - MirrorPodCount = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: MirrorPodCountKey, - Help: "The number of mirror pods the kubelet will try to create (one per admitted static pod)", - StabilityLevel: metrics.ALPHA, - }, - ) - // WorkingPodCount tracks the count of pods in each lifecycle phase, whether they are static pods, and whether they are desired, orphaned, or runtime_only - WorkingPodCount = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: WorkingPodCountKey, - Help: "Number of pods the kubelet is actually running, broken down by lifecycle phase, whether the pod is desired, orphaned, or runtime only (also orphaned), and whether the pod is static. An orphaned pod has been removed from local configuration or force deleted in the API and consumes resources that are not otherwise visible.", - StabilityLevel: metrics.ALPHA, - }, - []string{"lifecycle", "config", "static"}, - ) - // OrphanedRuntimePodTotal is incremented every time a pod is detected in the runtime without being known to the pod worker first - OrphanedRuntimePodTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: OrphanedRuntimePodTotalKey, - Help: "Number of pods that have been detected in the container runtime without being already known to the pod worker. This typically indicates the kubelet was restarted while a pod was force deleted in the API or in the local configuration, which is unusual.", - StabilityLevel: metrics.ALPHA, - }, - ) - // RestartedPodTotal is incremented every time a pod with the same UID is deleted and recreated - RestartedPodTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: RestartedPodTotalKey, - Help: "Number of pods that have been restarted because they were deleted and recreated with the same UID while the kubelet was watching them (common for static pods, extremely uncommon for API pods)", - StabilityLevel: metrics.ALPHA, - }, - []string{"static"}, - ) - // StartedPodsTotal is a counter that tracks pod sandbox creation operations - StartedPodsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: StartedPodsTotalKey, - Help: "Cumulative number of pods started", - StabilityLevel: metrics.ALPHA, - }, - ) - // StartedPodsErrorsTotal is a counter that tracks the number of errors creating pod sandboxes - StartedPodsErrorsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: StartedPodsErrorsTotalKey, - Help: "Cumulative number of errors when starting pods", - StabilityLevel: metrics.ALPHA, - }, - ) - // StartedContainersTotal is a counter that tracks the number of container creation operations - StartedContainersTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: StartedContainersTotalKey, - Help: "Cumulative number of containers started", - StabilityLevel: metrics.ALPHA, - }, - []string{"container_type"}, - ) - // StartedContainersTotal is a counter that tracks the number of errors creating containers - StartedContainersErrorsTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: StartedContainersErrorsTotalKey, - Help: "Cumulative number of errors when starting containers", - StabilityLevel: metrics.ALPHA, - }, - []string{"container_type", "code"}, - ) - // StartedHostProcessContainersTotal is a counter that tracks the number of hostprocess container creation operations - StartedHostProcessContainersTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: StartedHostProcessContainersTotalKey, - Help: "Cumulative number of hostprocess containers started. This metric will only be collected on Windows.", - StabilityLevel: metrics.ALPHA, - }, - []string{"container_type"}, - ) - // StartedHostProcessContainersErrorsTotal is a counter that tracks the number of errors creating hostprocess containers - StartedHostProcessContainersErrorsTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: StartedHostProcessContainersErrorsTotalKey, - Help: "Cumulative number of errors when starting hostprocess containers. This metric will only be collected on Windows.", - StabilityLevel: metrics.ALPHA, - }, - []string{"container_type", "code"}, - ) - // ManagedEphemeralContainers is a gauge that indicates how many ephemeral containers are managed by this kubelet. - ManagedEphemeralContainers = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: ManagedEphemeralContainersKey, - Help: "Current number of ephemeral containers in pods managed by this kubelet.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // GracefulShutdownStartTime is a gauge that records the time at which the kubelet started graceful shutdown. - GracefulShutdownStartTime = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: "graceful_shutdown_start_time_seconds", - Help: "Last graceful shutdown start time since unix epoch in seconds", - StabilityLevel: metrics.ALPHA, - }, - ) - - // GracefulShutdownEndTime is a gauge that records the time at which the kubelet completed graceful shutdown. - GracefulShutdownEndTime = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: "graceful_shutdown_end_time_seconds", - Help: "Last graceful shutdown end time since unix epoch in seconds", - StabilityLevel: metrics.ALPHA, - }, - ) - - LifecycleHandlerHTTPFallbacks = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: "lifecycle_handler_http_fallbacks_total", - Help: "The number of times lifecycle handlers successfully fell back to http from https.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // CPUManagerPinningRequestsTotal tracks the number of times the pod spec will cause the cpu manager to pin cores - CPUManagerPinningRequestsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: CPUManagerPinningRequestsTotalKey, - Help: "The number of cpu core allocations which required pinning.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // CPUManagerPinningErrorsTotal tracks the number of times the pod spec required the cpu manager to pin cores, but the allocation failed - CPUManagerPinningErrorsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: CPUManagerPinningErrorsTotalKey, - Help: "The number of cpu core allocations which required pinning failed.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // CPUManagerSharedPoolSizeMilliCores reports the current size of the shared CPU pool for non-guaranteed pods - CPUManagerSharedPoolSizeMilliCores = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: CPUManagerSharedPoolSizeMilliCoresKey, - Help: "The size of the shared CPU pool for non-guaranteed QoS pods, in millicores.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // CPUManagerExclusiveCPUsAllocationCount reports the total number of CPUs exclusively allocated to containers running on this node - CPUManagerExclusiveCPUsAllocationCount = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: CPUManagerExclusiveCPUsAllocationCountKey, - Help: "The total number of CPUs exclusively allocated to containers running on this node", - StabilityLevel: metrics.ALPHA, - }, - ) - - // CPUManagerAllocationPerNUMA tracks the count of CPUs allocated per NUMA node - CPUManagerAllocationPerNUMA = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: CPUManagerAllocationPerNUMAKey, - Help: "Number of CPUs allocated per NUMA node", - StabilityLevel: metrics.ALPHA, - }, - []string{AlignedNUMANode}, - ) - - // ContainerAlignedComputeResources reports the count of resources allocation which granted aligned resources, per alignment boundary - ContainerAlignedComputeResources = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: ContainerAlignedComputeResourcesNameKey, - Help: "Cumulative number of aligned compute resources allocated to containers by alignment type.", - StabilityLevel: metrics.ALPHA, - }, - []string{ContainerAlignedComputeResourcesScopeLabelKey, ContainerAlignedComputeResourcesBoundaryLabelKey}, - ) - - // ContainerAlignedComputeResourcesFailure reports the count of resources allocation attempts which failed to align resources, per alignment boundary - ContainerAlignedComputeResourcesFailure = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: ContainerAlignedComputeResourcesFailureNameKey, - Help: "Cumulative number of failures to allocate aligned compute resources to containers by alignment type.", - StabilityLevel: metrics.ALPHA, - }, - []string{ContainerAlignedComputeResourcesScopeLabelKey, ContainerAlignedComputeResourcesBoundaryLabelKey}, - ) - - MemoryManagerPinningRequestTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: MemoryManagerPinningRequestsTotalKey, - Help: "The number of memory pages allocations which required pinning.", - StabilityLevel: metrics.ALPHA, - }) - - // MemoryManagerPinningErrorsTotal tracks the number of times the pod spec required the memory manager to pin memory pages, but the allocation failed - MemoryManagerPinningErrorsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: MemoryManagerPinningErrorsTotalKey, - Help: "The number of memory pages allocations which required pinning that failed.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // TopologyManagerAdmissionRequestsTotal tracks the number of times the pod spec will cause the topology manager to admit a pod - TopologyManagerAdmissionRequestsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: TopologyManagerAdmissionRequestsTotalKey, - Help: "The number of admission requests where resources have to be aligned.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // TopologyManagerAdmissionErrorsTotal tracks the number of times the pod spec required the topology manager to admit a pod, but the admission failed - TopologyManagerAdmissionErrorsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: TopologyManagerAdmissionErrorsTotalKey, - Help: "The number of admission request failures where resources could not be aligned.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // TopologyManagerAdmissionDuration is a Histogram that tracks the duration (in seconds) to serve a pod admission request. - TopologyManagerAdmissionDuration = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: TopologyManagerAdmissionDurationKey, - Help: "Duration in milliseconds to serve a pod admission request.", - Buckets: metrics.ExponentialBuckets(.05, 2, 15), - StabilityLevel: metrics.ALPHA, - }, - ) - - // OrphanPodCleanedVolumes is number of orphaned Pods that times that removeOrphanedPodVolumeDirs was called during the last sweep. - OrphanPodCleanedVolumes = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: orphanPodCleanedVolumesKey, - Help: "The total number of orphaned Pods whose volumes were cleaned in the last periodic sweep.", - StabilityLevel: metrics.ALPHA, - }, - ) - // OrphanPodCleanedVolumes is number of times that removeOrphanedPodVolumeDirs failed. - OrphanPodCleanedVolumesErrors = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: orphanPodCleanedVolumesErrorsKey, - Help: "The number of orphaned Pods whose volumes failed to be cleaned in the last periodic sweep.", - StabilityLevel: metrics.ALPHA, - }, - ) - - NodeStartupPreKubeletDuration = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: NodeStartupPreKubeletKey, - Help: "Duration in seconds of node startup before kubelet starts.", - StabilityLevel: metrics.ALPHA, - }, - ) - - NodeStartupPreRegistrationDuration = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: NodeStartupPreRegistrationKey, - Help: "Duration in seconds of node startup before registration.", - StabilityLevel: metrics.ALPHA, - }, - ) - - NodeStartupRegistrationDuration = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: NodeStartupRegistrationKey, - Help: "Duration in seconds of node startup during registration.", - StabilityLevel: metrics.ALPHA, - }, - ) - - NodeStartupPostRegistrationDuration = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: NodeStartupPostRegistrationKey, - Help: "Duration in seconds of node startup after registration.", - StabilityLevel: metrics.ALPHA, - }, - ) - - NodeStartupDuration = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: NodeStartupKey, - Help: "Duration in seconds of node startup in total.", - StabilityLevel: metrics.ALPHA, - }, - ) - - ImageGarbageCollectedTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: ImageGarbageCollectedTotalKey, - Help: "Total number of images garbage collected by the kubelet, whether through disk usage or image age.", - StabilityLevel: metrics.ALPHA, - }, - []string{"reason"}, - ) - - // ImagePullDuration is a Histogram that tracks the duration (in seconds) it takes for an image to be pulled, - // including the time spent in the waiting queue of image puller. - // The metric is broken down by bucketed image size. - ImagePullDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: KubeletSubsystem, - Name: ImagePullDurationKey, - Help: "Duration in seconds to pull an image.", - Buckets: imagePullDurationBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"image_size_in_bytes"}, - ) - - LifecycleHandlerSleepTerminated = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: "sleep_action_terminated_early_total", - Help: "The number of times lifecycle sleep handler got terminated before it finishes", - StabilityLevel: metrics.ALPHA, - }, - ) - - CgroupVersion = metrics.NewGauge( - &metrics.GaugeOpts{ - Subsystem: KubeletSubsystem, - Name: CgroupVersionKey, - Help: "cgroup version on the hosts.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // DRAOperationsDuration tracks the duration of the DRA PrepareResources and UnprepareResources requests. - DRAOperationsDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: DRASubsystem, - Name: DRAOperationsDurationKey, - Help: "Latency histogram in seconds for the duration of handling all ResourceClaims referenced by a pod when the pod starts or stops. Identified by the name of the operation (PrepareResources or UnprepareResources) and separated by the success of the operation. The number of failed operations is provided through the histogram's overall count.", - Buckets: DRADurationBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"operation_name", "is_error"}, - ) - - // DRAGRPCOperationsDuration tracks the duration of the DRA GRPC operations. - DRAGRPCOperationsDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: DRASubsystem, - Name: DRAGRPCOperationsDurationKey, - Help: "Duration in seconds of the DRA gRPC operations", - Buckets: DRADurationBuckets, - StabilityLevel: metrics.ALPHA, - }, - []string{"driver_name", "method_name", "grpc_status_code"}, - ) - - // AdmissionRejectionsTotal tracks the number of failed admission times, currently, just record it for pod additions - AdmissionRejectionsTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: AdmissionRejectionsTotalKey, - Help: "Cumulative number pod admission rejections by the Kubelet.", - StabilityLevel: metrics.ALPHA, - }, - []string{"reason"}, - ) - - // ImageVolumeRequestedTotal trakcs the number of requested image volumes. - ImageVolumeRequestedTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: ImageVolumeRequestedTotalKey, - Help: "Number of requested image volumes.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // ImageVolumeMountedSucceedTotal tracks the number of successful image volume mounts. - ImageVolumeMountedSucceedTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: ImageVolumeMountedSucceedTotalKey, - Help: "Number of successful image volume mounts.", - StabilityLevel: metrics.ALPHA, - }, - ) - - // ImageVolumeMountedErrorsTotal tracks the number of failed image volume mounts. - ImageVolumeMountedErrorsTotal = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: KubeletSubsystem, - Name: ImageVolumeMountedErrorsTotalKey, - Help: "Number of failed image volume mounts.", - StabilityLevel: metrics.ALPHA, - }, - ) -) - -var registerMetrics sync.Once - -// Register registers all metrics. -func Register(collectors ...metrics.StableCollector) { - // Register the metrics. - registerMetrics.Do(func() { - legacyregistry.MustRegister(FirstNetworkPodStartSLIDuration) - legacyregistry.MustRegister(NodeName) - legacyregistry.MustRegister(PodWorkerDuration) - legacyregistry.MustRegister(PodStartDuration) - legacyregistry.MustRegister(PodStartSLIDuration) - legacyregistry.MustRegister(PodStartTotalDuration) - legacyregistry.MustRegister(ImagePullDuration) - legacyregistry.MustRegister(ImageGarbageCollectedTotal) - legacyregistry.MustRegister(NodeStartupPreKubeletDuration) - legacyregistry.MustRegister(NodeStartupPreRegistrationDuration) - legacyregistry.MustRegister(NodeStartupRegistrationDuration) - legacyregistry.MustRegister(NodeStartupPostRegistrationDuration) - legacyregistry.MustRegister(NodeStartupDuration) - legacyregistry.MustRegister(CgroupManagerDuration) - legacyregistry.MustRegister(PodWorkerStartDuration) - legacyregistry.MustRegister(PodStatusSyncDuration) - legacyregistry.MustRegister(ContainersPerPodCount) - legacyregistry.MustRegister(PLEGRelistDuration) - legacyregistry.MustRegister(PLEGDiscardEvents) - legacyregistry.MustRegister(PLEGRelistInterval) - legacyregistry.MustRegister(PLEGLastSeen) - legacyregistry.MustRegister(EventedPLEGConnErr) - legacyregistry.MustRegister(EventedPLEGConn) - legacyregistry.MustRegister(EventedPLEGConnLatency) - legacyregistry.MustRegister(RuntimeOperations) - legacyregistry.MustRegister(RuntimeOperationsDuration) - legacyregistry.MustRegister(RuntimeOperationsErrors) - legacyregistry.MustRegister(Evictions) - legacyregistry.MustRegister(EvictionStatsAge) - legacyregistry.MustRegister(Preemptions) - legacyregistry.MustRegister(DevicePluginRegistrationCount) - legacyregistry.MustRegister(DevicePluginAllocationDuration) - legacyregistry.MustRegister(RunningContainerCount) - legacyregistry.MustRegister(RunningPodCount) - legacyregistry.MustRegister(DesiredPodCount) - legacyregistry.MustRegister(ActivePodCount) - legacyregistry.MustRegister(MirrorPodCount) - legacyregistry.MustRegister(WorkingPodCount) - legacyregistry.MustRegister(OrphanedRuntimePodTotal) - legacyregistry.MustRegister(RestartedPodTotal) - legacyregistry.MustRegister(ManagedEphemeralContainers) - legacyregistry.MustRegister(PodResourcesEndpointRequestsTotalCount) - legacyregistry.MustRegister(PodResourcesEndpointRequestsListCount) - legacyregistry.MustRegister(PodResourcesEndpointRequestsGetAllocatableCount) - legacyregistry.MustRegister(PodResourcesEndpointErrorsListCount) - legacyregistry.MustRegister(PodResourcesEndpointErrorsGetAllocatableCount) - if utilfeature.DefaultFeatureGate.Enabled(features.KubeletPodResourcesGet) { - legacyregistry.MustRegister(PodResourcesEndpointRequestsGetCount) - legacyregistry.MustRegister(PodResourcesEndpointErrorsGetCount) - } - legacyregistry.MustRegister(StartedPodsTotal) - legacyregistry.MustRegister(StartedPodsErrorsTotal) - legacyregistry.MustRegister(StartedContainersTotal) - legacyregistry.MustRegister(StartedContainersErrorsTotal) - legacyregistry.MustRegister(StartedHostProcessContainersTotal) - legacyregistry.MustRegister(StartedHostProcessContainersErrorsTotal) - legacyregistry.MustRegister(RunPodSandboxDuration) - legacyregistry.MustRegister(RunPodSandboxErrors) - legacyregistry.MustRegister(CPUManagerPinningRequestsTotal) - legacyregistry.MustRegister(CPUManagerPinningErrorsTotal) - legacyregistry.MustRegister(CPUManagerSharedPoolSizeMilliCores) - legacyregistry.MustRegister(CPUManagerExclusiveCPUsAllocationCount) - legacyregistry.MustRegister(CPUManagerAllocationPerNUMA) - legacyregistry.MustRegister(ContainerAlignedComputeResources) - legacyregistry.MustRegister(ContainerAlignedComputeResourcesFailure) - legacyregistry.MustRegister(MemoryManagerPinningRequestTotal) - legacyregistry.MustRegister(MemoryManagerPinningErrorsTotal) - legacyregistry.MustRegister(TopologyManagerAdmissionRequestsTotal) - legacyregistry.MustRegister(TopologyManagerAdmissionErrorsTotal) - legacyregistry.MustRegister(TopologyManagerAdmissionDuration) - legacyregistry.MustRegister(OrphanPodCleanedVolumes) - legacyregistry.MustRegister(OrphanPodCleanedVolumesErrors) - - for _, collector := range collectors { - legacyregistry.CustomMustRegister(collector) - } - - if utilfeature.DefaultFeatureGate.Enabled(features.GracefulNodeShutdown) && - utilfeature.DefaultFeatureGate.Enabled(features.GracefulNodeShutdownBasedOnPodPriority) { - legacyregistry.MustRegister(GracefulShutdownStartTime) - legacyregistry.MustRegister(GracefulShutdownEndTime) - } - - legacyregistry.MustRegister(LifecycleHandlerHTTPFallbacks) - legacyregistry.MustRegister(LifecycleHandlerSleepTerminated) - legacyregistry.MustRegister(CgroupVersion) - - if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - legacyregistry.MustRegister(DRAOperationsDuration) - legacyregistry.MustRegister(DRAGRPCOperationsDuration) - } - - legacyregistry.MustRegister(AdmissionRejectionsTotal) - - if utilfeature.DefaultFeatureGate.Enabled(features.ImageVolume) { - legacyregistry.MustRegister(ImageVolumeRequestedTotal) - legacyregistry.MustRegister(ImageVolumeMountedSucceedTotal) - legacyregistry.MustRegister(ImageVolumeMountedErrorsTotal) - } - }) -} - -// GetGather returns the gatherer. It used by test case outside current package. -func GetGather() metrics.Gatherer { - return legacyregistry.DefaultGatherer -} - -// SinceInSeconds gets the time since the specified start in seconds. -func SinceInSeconds(start time.Time) float64 { - return time.Since(start).Seconds() -} - -// SetNodeName sets the NodeName Gauge to 1. -func SetNodeName(name types.NodeName) { - NodeName.WithLabelValues(string(name)).Set(1) -} - -func GetImageSizeBucket(sizeInBytes uint64) string { - if sizeInBytes == 0 { - return "N/A" - } - - for i := len(imageSizeBuckets) - 1; i >= 0; i-- { - if sizeInBytes > imageSizeBuckets[i].lowerBoundInBytes { - return imageSizeBuckets[i].label - } - } - - // return empty string when sizeInBytes is 0 (error getting image size) - return "" -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/actual_state_of_world.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/actual_state_of_world.go deleted file mode 100644 index cdaa42c0a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/actual_state_of_world.go +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Package cache implements data structures used by the kubelet plugin manager to -keep track of registered plugins. -*/ -package cache - -import ( - "fmt" - "sync" - "time" - - "k8s.io/apimachinery/pkg/types" - "k8s.io/klog/v2" -) - -// ActualStateOfWorld defines a set of thread-safe operations for the kubelet -// plugin manager's actual state of the world cache. -// This cache contains a map of socket file path to plugin information of -// all plugins attached to this node. -type ActualStateOfWorld interface { - - // GetRegisteredPlugins generates and returns a list of plugins - // that are successfully registered plugins in the current actual state of world. - GetRegisteredPlugins() []PluginInfo - - // AddPlugin add the given plugin in the cache. - // An error will be returned if socketPath of the PluginInfo object is empty. - // Note that this is different from desired world cache's AddOrUpdatePlugin - // because for the actual state of world cache, there won't be a scenario where - // we need to update an existing plugin if the timestamps don't match. This is - // because the plugin should have been unregistered in the reconciler and therefore - // removed from the actual state of world cache first before adding it back into - // the actual state of world cache again with the new timestamp - AddPlugin(pluginInfo PluginInfo) error - - // RemovePlugin deletes the plugin with the given socket path from the actual - // state of world. - // If a plugin does not exist with the given socket path, this is a no-op. - RemovePlugin(socketPath string) - - // PluginExistsWithCorrectTimestamp checks if the given plugin exists in the current actual - // state of world cache with the correct timestamp. - // Deprecated: please use `PluginExistsWithCorrectUUID` instead as it provides a better - // cross-platform support - PluginExistsWithCorrectTimestamp(pluginInfo PluginInfo) bool - - // PluginExistsWithCorrectUUID checks if the given plugin exists in the current actual - // state of world cache with the correct UUID - PluginExistsWithCorrectUUID(pluginInfo PluginInfo) bool -} - -// NewActualStateOfWorld returns a new instance of ActualStateOfWorld -func NewActualStateOfWorld() ActualStateOfWorld { - return &actualStateOfWorld{ - socketFileToInfo: make(map[string]PluginInfo), - } -} - -type actualStateOfWorld struct { - - // socketFileToInfo is a map containing the set of successfully registered plugins - // The keys are plugin socket file paths. The values are PluginInfo objects - socketFileToInfo map[string]PluginInfo - sync.RWMutex -} - -var _ ActualStateOfWorld = &actualStateOfWorld{} - -// PluginInfo holds information of a plugin -type PluginInfo struct { - SocketPath string - Timestamp time.Time - UUID types.UID - Handler PluginHandler - Name string - Endpoint string -} - -func (asw *actualStateOfWorld) AddPlugin(pluginInfo PluginInfo) error { - asw.Lock() - defer asw.Unlock() - - if pluginInfo.SocketPath == "" { - return fmt.Errorf("socket path is empty") - } - if _, ok := asw.socketFileToInfo[pluginInfo.SocketPath]; ok { - klog.V(2).InfoS("Plugin exists in actual state cache", "path", pluginInfo.SocketPath) - } - asw.socketFileToInfo[pluginInfo.SocketPath] = pluginInfo - return nil -} - -func (asw *actualStateOfWorld) RemovePlugin(socketPath string) { - asw.Lock() - defer asw.Unlock() - - delete(asw.socketFileToInfo, socketPath) -} - -func (asw *actualStateOfWorld) GetRegisteredPlugins() []PluginInfo { - asw.RLock() - defer asw.RUnlock() - - currentPlugins := []PluginInfo{} - for _, pluginInfo := range asw.socketFileToInfo { - currentPlugins = append(currentPlugins, pluginInfo) - } - return currentPlugins -} - -func (asw *actualStateOfWorld) PluginExistsWithCorrectTimestamp(pluginInfo PluginInfo) bool { - asw.RLock() - defer asw.RUnlock() - - // We need to check both if the socket file path exists, and the timestamp - // matches the given plugin (from the desired state cache) timestamp - actualStatePlugin, exists := asw.socketFileToInfo[pluginInfo.SocketPath] - return exists && (actualStatePlugin.Timestamp == pluginInfo.Timestamp) -} - -func (asw *actualStateOfWorld) PluginExistsWithCorrectUUID(pluginInfo PluginInfo) bool { - asw.RLock() - defer asw.RUnlock() - - // We need to check both if the socket file path exists, and the UUID - // matches the given plugin (from the desired state cache) UUID - actualStatePlugin, exists := asw.socketFileToInfo[pluginInfo.SocketPath] - return exists && (actualStatePlugin.UUID == pluginInfo.UUID) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/desired_state_of_world.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/desired_state_of_world.go deleted file mode 100644 index 90e38ddd7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/desired_state_of_world.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -/* -Package cache implements data structures used by the kubelet plugin manager to -keep track of registered plugins. -*/ -package cache - -import ( - "errors" - "fmt" - "sync" - "time" - - "k8s.io/apimachinery/pkg/util/uuid" - "k8s.io/klog/v2" -) - -// DesiredStateOfWorld defines a set of thread-safe operations for the kubelet -// plugin manager's desired state of the world cache. -// This cache contains a map of socket file path to plugin information of -// all plugins attached to this node. -type DesiredStateOfWorld interface { - // AddOrUpdatePlugin add the given plugin in the cache if it doesn't already exist. - // If it does exist in the cache, then the timestamp of the PluginInfo object in the cache will be updated. - // An error will be returned if socketPath is empty. - AddOrUpdatePlugin(socketPath string) error - - // RemovePlugin deletes the plugin with the given socket path from the desired - // state of world. - // If a plugin does not exist with the given socket path, this is a no-op. - RemovePlugin(socketPath string) - - // GetPluginsToRegister generates and returns a list of plugins - // in the current desired state of world. - GetPluginsToRegister() []PluginInfo - - // PluginExists checks if the given socket path exists in the current desired - // state of world cache - PluginExists(socketPath string) bool -} - -// NewDesiredStateOfWorld returns a new instance of DesiredStateOfWorld. -func NewDesiredStateOfWorld() DesiredStateOfWorld { - return &desiredStateOfWorld{ - socketFileToInfo: make(map[string]PluginInfo), - } -} - -type desiredStateOfWorld struct { - - // socketFileToInfo is a map containing the set of successfully registered plugins - // The keys are plugin socket file paths. The values are PluginInfo objects - socketFileToInfo map[string]PluginInfo - sync.RWMutex -} - -var _ DesiredStateOfWorld = &desiredStateOfWorld{} - -// Generate a detailed error msg for logs -func generatePluginMsgDetailed(prefixMsg, suffixMsg, socketPath, details string) (detailedMsg string) { - return fmt.Sprintf("%v for plugin at %q %v %v", prefixMsg, socketPath, details, suffixMsg) -} - -// Generate a simplified error msg for events and a detailed error msg for logs -func generatePluginMsg(prefixMsg, suffixMsg, socketPath, details string) (simpleMsg, detailedMsg string) { - simpleMsg = fmt.Sprintf("%v for plugin at %q %v", prefixMsg, socketPath, suffixMsg) - return simpleMsg, generatePluginMsgDetailed(prefixMsg, suffixMsg, socketPath, details) -} - -// GenerateMsgDetailed returns detailed msgs for plugins to register -// that can be used in logs. -// The msg format follows the pattern " " -func (plugin *PluginInfo) GenerateMsgDetailed(prefixMsg, suffixMsg string) (detailedMsg string) { - detailedStr := fmt.Sprintf("(plugin details: %v)", plugin) - return generatePluginMsgDetailed(prefixMsg, suffixMsg, plugin.SocketPath, detailedStr) -} - -// GenerateMsg returns simple and detailed msgs for plugins to register -// that is user friendly and a detailed msg that can be used in logs. -// The msg format follows the pattern " ". -func (plugin *PluginInfo) GenerateMsg(prefixMsg, suffixMsg string) (simpleMsg, detailedMsg string) { - detailedStr := fmt.Sprintf("(plugin details: %v)", plugin) - return generatePluginMsg(prefixMsg, suffixMsg, plugin.SocketPath, detailedStr) -} - -// GenerateErrorDetailed returns detailed errors for plugins to register -// that can be used in logs. -// The msg format follows the pattern " : ", -func (plugin *PluginInfo) GenerateErrorDetailed(prefixMsg string, err error) (detailedErr error) { - return errors.New(plugin.GenerateMsgDetailed(prefixMsg, errSuffix(err))) -} - -// GenerateError returns simple and detailed errors for plugins to register -// that is user friendly and a detailed error that can be used in logs. -// The msg format follows the pattern " : ". -func (plugin *PluginInfo) GenerateError(prefixMsg string, err error) (simpleErr, detailedErr error) { - simpleMsg, detailedMsg := plugin.GenerateMsg(prefixMsg, errSuffix(err)) - return errors.New(simpleMsg), errors.New(detailedMsg) -} - -// Generates an error string with the format ": " if err exists -func errSuffix(err error) string { - errStr := "" - if err != nil { - errStr = fmt.Sprintf(": %v", err) - } - return errStr -} - -func (dsw *desiredStateOfWorld) AddOrUpdatePlugin(socketPath string) error { - dsw.Lock() - defer dsw.Unlock() - - if socketPath == "" { - return fmt.Errorf("socket path is empty") - } - if _, ok := dsw.socketFileToInfo[socketPath]; ok { - klog.V(2).InfoS("Plugin exists in desired state cache, timestamp will be updated", "path", socketPath) - } - - // Update the PluginInfo object. - // Note that we only update the timestamp and UUID in the desired state of world, not the actual state of world - // because in the reconciler, we need to check if the plugin in the actual state of world is the same - // version as the plugin in the desired state of world - dsw.socketFileToInfo[socketPath] = PluginInfo{ - SocketPath: socketPath, - Timestamp: time.Now(), - UUID: uuid.NewUUID(), - } - return nil -} - -func (dsw *desiredStateOfWorld) RemovePlugin(socketPath string) { - dsw.Lock() - defer dsw.Unlock() - - delete(dsw.socketFileToInfo, socketPath) -} - -func (dsw *desiredStateOfWorld) GetPluginsToRegister() []PluginInfo { - dsw.RLock() - defer dsw.RUnlock() - - pluginsToRegister := []PluginInfo{} - for _, pluginInfo := range dsw.socketFileToInfo { - pluginsToRegister = append(pluginsToRegister, pluginInfo) - } - return pluginsToRegister -} - -func (dsw *desiredStateOfWorld) PluginExists(socketPath string) bool { - dsw.RLock() - defer dsw.RUnlock() - - _, exists := dsw.socketFileToInfo[socketPath] - return exists -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/types.go deleted file mode 100644 index bcffd117e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache/types.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cache - -import "time" - -// PluginHandler is an interface a client of the pluginwatcher API needs to implement in -// order to consume plugins -// The PluginHandler follows the simple following state machine: -// -// +--------------------------------------+ -// | ReRegistration | -// | Socket created with same plugin name | -// | | -// | | -// Socket Created v + Socket Deleted -// +------------------> Validate +---------------------------> Register +------------------> DeRegister -// + + + -// | | | -// | Error | Error | -// | | | -// v v v -// Out Out Out -// -// The pluginwatcher module follows strictly and sequentially this state machine for each *plugin name*. -// e.g: If you are Registering a plugin foo, you cannot get a DeRegister call for plugin foo -// until the Register("foo") call returns. Nor will you get a Validate("foo", "Different endpoint", ...) -// call until the Register("foo") call returns. -// -// ReRegistration: Socket created with same plugin name, usually for a plugin update -// e.g: plugin with name foo registers at foo.com/foo-1.9.7 later a plugin with name foo -// registers at foo.com/foo-1.9.9 -// -// DeRegistration: When ReRegistration happens only the deletion of the new socket will trigger a DeRegister call -type PluginHandler interface { - // Validate returns an error if the information provided by - // the potential plugin is erroneous (unsupported version, ...) - ValidatePlugin(pluginName string, endpoint string, versions []string) error - // RegisterPlugin is called so that the plugin can be registered by any - // plugin consumer - // Error encountered here can still be Notified to the plugin. - RegisterPlugin(pluginName, endpoint string, versions []string, pluginClientTimeout *time.Duration) error - // DeRegisterPlugin is called once the pluginwatcher observes that the socket has - // been deleted. - DeRegisterPlugin(pluginName, endpoint string) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/doc.go deleted file mode 100644 index acd561b21..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/doc.go +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package qos contains helper functions for quality of service. -// For each resource (memory, CPU) Kubelet supports three classes of containers. -// Memory guaranteed containers will receive the highest priority and will get all the resources -// they need. -// Burstable containers will be guaranteed their request and can "burst" and use more resources -// when available. -// Best-Effort containers, which don't specify a request, can use resources only if not being used -// by other pods. -package qos diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/helpers.go b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/helpers.go deleted file mode 100644 index 33b6c166b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/helpers.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package qos contains helper functions for quality of service. -// For each resource (memory, CPU) Kubelet supports three classes of containers. -// Memory guaranteed containers will receive the highest priority and will get all the resources -// they need. -// Burstable containers will be guaranteed their request and can "burst" and use more resources -// when available. -// Best-Effort containers, which don't specify a request, can use resources only if not being used -// by other pods. - -package qos - -import ( - v1 "k8s.io/api/core/v1" - resourcehelper "k8s.io/component-helpers/resource" -) - -// minRegularContainerMemory returns the minimum memory resource quantity -// across all regular containers in pod.Spec.Containers. -// It does not include initContainers (both restartable and non-restartable). -func minRegularContainerMemory(pod v1.Pod) int64 { - memoryValue := pod.Spec.Containers[0].Resources.Requests.Memory().Value() - for _, container := range pod.Spec.Containers[1:] { - if container.Resources.Requests.Memory().Value() < memoryValue { - memoryValue = container.Resources.Requests.Memory().Value() - } - } - return memoryValue -} - -// remainingPodMemReqPerContainer calculates the remaining pod memory request per -// container by: -// 1. Taking the total pod memory requests -// 2. Subtracting total container memory requests from pod memory requests -// 3. Dividing the remainder by the number of containers. -// This gives us the additional memory request that is not allocated to any -// containers in the pod. This value will be divided equally among all containers to -// calculate oom score adjusment. -// See https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2837-pod-level-resource-spec/README.md#oom-score-adjustment -// for more details. -func remainingPodMemReqPerContainer(pod *v1.Pod) int64 { - var remainingMemory int64 - if pod.Spec.Resources.Requests.Memory().IsZero() { - return remainingMemory - } - - numContainers := len(pod.Spec.Containers) + len(pod.Spec.InitContainers) - - // Aggregated requests of all containers. - aggrContainerReqs := resourcehelper.AggregateContainerRequests(pod, resourcehelper.PodResourcesOptions{}) - - remainingMemory = pod.Spec.Resources.Requests.Memory().Value() - aggrContainerReqs.Memory().Value() - - remainingMemoryPerContainer := remainingMemory / int64(numContainers) - return remainingMemoryPerContainer -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/policy.go b/vendor/k8s.io/kubernetes/pkg/kubelet/qos/policy.go deleted file mode 100644 index a70945ed2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/qos/policy.go +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package qos - -import ( - v1 "k8s.io/api/core/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" - resourcehelper "k8s.io/component-helpers/resource" - v1qos "k8s.io/kubernetes/pkg/apis/core/v1/helper/qos" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/kubelet/types" -) - -const ( - // KubeletOOMScoreAdj is the OOM score adjustment for Kubelet - KubeletOOMScoreAdj int = -999 - // KubeProxyOOMScoreAdj is the OOM score adjustment for kube-proxy - KubeProxyOOMScoreAdj int = -999 - guaranteedOOMScoreAdj int = -997 - besteffortOOMScoreAdj int = 1000 -) - -// GetContainerOOMScoreAdjust returns the amount by which the OOM score of all processes in the -// container should be adjusted. -// The OOM score of a process is the percentage of memory it consumes -// multiplied by 10 (barring exceptional cases) + a configurable quantity which is between -1000 -// and 1000. Containers with higher OOM scores are killed if the system runs out of memory. -// See https://lwn.net/Articles/391222/ for more information. -// OOMScoreAdjust should be calculated based on the allocated resources, so the pod argument should -// contain the allocated resources in the spec. -func GetContainerOOMScoreAdjust(pod *v1.Pod, container *v1.Container, memoryCapacity int64) int { - if types.IsNodeCriticalPod(pod) { - // Only node critical pod should be the last to get killed. - return guaranteedOOMScoreAdj - } - - switch v1qos.GetPodQOS(pod) { - case v1.PodQOSGuaranteed: - // Guaranteed containers should be the last to get killed. - return guaranteedOOMScoreAdj - case v1.PodQOSBestEffort: - return besteffortOOMScoreAdj - } - - // Burstable containers are a middle tier, between Guaranteed and Best-Effort. Ideally, - // we want to protect Burstable containers that consume less memory than requested. - // The formula below is a heuristic. A container requesting for 10% of a system's - // memory will have an OOM score adjust of 900. If a process in container Y - // uses over 10% of memory, its OOM score will be 1000. The idea is that containers - // which use more than their request will have an OOM score of 1000 and will be prime - // targets for OOM kills. - // Note that this is a heuristic, it won't work if a container has many small processes. - containerMemReq := container.Resources.Requests.Memory().Value() - - var oomScoreAdjust, remainingReqPerContainer int64 - // When PodLevelResources feature is enabled, the OOM score adjustment formula is modified - // to account for pod-level memory requests. Any extra pod memory request that's - // not allocated to the containers is divided equally among all containers and - // added to their individual memory requests when calculating the OOM score - // adjustment. Otherwise, only container-level memory requests are used. See - // https://github.com/kubernetes/enhancements/blob/master/keps/sig-node/2837-pod-level-resource-spec/README.md#oom-score-adjustment - // for more details. - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && - resourcehelper.IsPodLevelRequestsSet(pod) { - // TODO(ndixita): Refactor to use this formula in all cases, as - // remainingReqPerContainer will be 0 when pod-level resources are not set. - remainingReqPerContainer = remainingPodMemReqPerContainer(pod) - oomScoreAdjust = 1000 - (1000 * (containerMemReq + remainingReqPerContainer) / memoryCapacity) - } else { - oomScoreAdjust = 1000 - (1000*containerMemReq)/memoryCapacity - } - - // adapt the sidecarContainer memoryRequest for OOM ADJ calculation - // calculate the oom score adjustment based on: max-memory( currentSideCarContainer , min-memory(regular containers) ) . - if isSidecarContainer(pod, container) { - // check min memory quantity in regular containers - minMemoryRequest := minRegularContainerMemory(*pod) - - // When calculating minMemoryOomScoreAdjust for sidecar containers with PodLevelResources enabled, - // we add the per-container share of unallocated pod memory requests to the minimum memory request. - // This ensures the OOM score adjustment i.e. minMemoryOomScoreAdjust - // calculation remains consistent - // with how we handle pod-level memory requests for regular containers. - if utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) && - resourcehelper.IsPodLevelRequestsSet(pod) { - minMemoryRequest += remainingReqPerContainer - } - minMemoryOomScoreAdjust := 1000 - (1000*minMemoryRequest)/memoryCapacity - // the OOM adjustment for sidecar container will match - // or fall below the OOM score adjustment of regular containers in the Pod. - if oomScoreAdjust > minMemoryOomScoreAdjust { - oomScoreAdjust = minMemoryOomScoreAdjust - } - } - - // A guaranteed pod using 100% of memory can have an OOM score of 10. Ensure - // that burstable pods have a higher OOM score adjustment. - if int(oomScoreAdjust) < (1000 + guaranteedOOMScoreAdj) { - return (1000 + guaranteedOOMScoreAdj) - } - // Give burstable pods a higher chance of survival over besteffort pods. - if int(oomScoreAdjust) == besteffortOOMScoreAdj { - return int(oomScoreAdjust - 1) - } - return int(oomScoreAdjust) -} - -// isSidecarContainer returns a boolean indicating whether a container is a sidecar or not. -// Since v1.Container does not directly specify whether a container is a sidecar, -// this function uses available indicators (container.RestartPolicy == v1.ContainerRestartPolicyAlways) -// to make that determination. -func isSidecarContainer(pod *v1.Pod, container *v1.Container) bool { - if container.RestartPolicy != nil && *container.RestartPolicy == v1.ContainerRestartPolicyAlways { - for _, initContainer := range pod.Spec.InitContainers { - if initContainer.Name == container.Name { - return true - } - } - } - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit.go deleted file mode 100644 index 7356fa9c4..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package pidlimit - -import ( - "k8s.io/api/core/v1" -) - -const ( - // PIDs is the (internal) name for this resource - PIDs v1.ResourceName = "pid" -) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go deleted file mode 100644 index 25e765520..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_linux.go +++ /dev/null @@ -1,87 +0,0 @@ -//go:build linux -// +build linux - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package pidlimit - -import ( - "fmt" - "os" - "strconv" - "strings" - "syscall" - "time" - - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - statsapi "k8s.io/kubelet/pkg/apis/stats/v1alpha1" -) - -// Stats provides basic information about max and current process count -func Stats() (*statsapi.RlimitStats, error) { - rlimit := &statsapi.RlimitStats{} - - taskMax := int64(-1) - // Calculate the minimum of kernel.pid_max and kernel.threads-max as they both specify the - // system-wide limit on the number of tasks. - for _, file := range []string{"/proc/sys/kernel/pid_max", "/proc/sys/kernel/threads-max"} { - if content, err := os.ReadFile(file); err == nil { - if limit, err := strconv.ParseInt(string(content[:len(content)-1]), 10, 64); err == nil { - if taskMax == -1 || taskMax > limit { - taskMax = limit - } - } - } - } - // Both reads did not fail. - if taskMax >= 0 { - rlimit.MaxPID = &taskMax - } - - // Prefer to read "/proc/loadavg" when possible because sysinfo(2) - // returns truncated number when greater than 65538. See - // https://github.com/kubernetes/kubernetes/issues/107107 - if procs, err := runningTaskCount(); err == nil { - rlimit.NumOfRunningProcesses = &procs - } else { - var info syscall.Sysinfo_t - syscall.Sysinfo(&info) - procs := int64(info.Procs) - rlimit.NumOfRunningProcesses = &procs - } - - rlimit.Time = v1.NewTime(time.Now()) - - return rlimit, nil -} - -func runningTaskCount() (int64, error) { - // Example: 1.36 3.49 4.53 2/3518 3715089 - bytes, err := os.ReadFile("/proc/loadavg") - if err != nil { - return 0, err - } - fields := strings.Fields(string(bytes)) - if len(fields) < 5 { - return 0, fmt.Errorf("not enough fields in /proc/loadavg") - } - subfields := strings.Split(fields[3], "/") - if len(subfields) != 2 { - return 0, fmt.Errorf("error parsing fourth field of /proc/loadavg") - } - return strconv.ParseInt(subfields[1], 10, 64) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go deleted file mode 100644 index 805c276d9..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/stats/pidlimit/pidlimit_unsupported.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build !linux -// +build !linux - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package pidlimit - -import ( - statsapi "k8s.io/kubelet/pkg/apis/stats/v1alpha1" -) - -// Stats provides basic information about max and current process count -func Stats() (*statsapi.RlimitStats, error) { - return nil, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/status/.mockery.yaml b/vendor/k8s.io/kubernetes/pkg/kubelet/status/.mockery.yaml deleted file mode 100644 index e57d22e2e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/status/.mockery.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -dir: testing -filename: "mock_{{.InterfaceName | snakecase}}.go" -boilerplate-file: ../../../hack/boilerplate/boilerplate.generatego.txt -outpkg: testing -with-expecter: true -packages: - k8s.io/kubernetes/pkg/kubelet/status: - interfaces: - PodStatusProvider: diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go b/vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go deleted file mode 100644 index d519bf4c7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/status/generate.go +++ /dev/null @@ -1,302 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package status - -import ( - "fmt" - "strings" - - v1 "k8s.io/api/core/v1" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - runtimeutil "k8s.io/kubernetes/pkg/kubelet/kuberuntime/util" -) - -const ( - // UnknownContainerStatuses says that all container statuses are unknown. - UnknownContainerStatuses = "UnknownContainerStatuses" - // PodCompleted says that all related containers have succeeded. - PodCompleted = "PodCompleted" - // PodFailed says that the pod has failed and as such the containers have failed. - PodFailed = "PodFailed" - // ContainersNotReady says that one or more containers are not ready. - ContainersNotReady = "ContainersNotReady" - // ContainersNotInitialized says that one or more init containers have not succeeded. - ContainersNotInitialized = "ContainersNotInitialized" - // ReadinessGatesNotReady says that one or more pod readiness gates are not ready. - ReadinessGatesNotReady = "ReadinessGatesNotReady" -) - -// GenerateContainersReadyCondition returns the status of "ContainersReady" condition. -// The status of "ContainersReady" condition is true when all containers are ready. -func GenerateContainersReadyCondition(pod *v1.Pod, oldPodStatus *v1.PodStatus, containerStatuses []v1.ContainerStatus, podPhase v1.PodPhase) v1.PodCondition { - // Find if all containers are ready or not. - if containerStatuses == nil { - return v1.PodCondition{ - Type: v1.ContainersReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.ContainersReady), - Status: v1.ConditionFalse, - Reason: UnknownContainerStatuses, - } - } - unknownContainers := []string{} - unreadyContainers := []string{} - - for _, container := range pod.Spec.InitContainers { - if !podutil.IsRestartableInitContainer(&container) { - continue - } - - if containerStatus, ok := podutil.GetContainerStatus(containerStatuses, container.Name); ok { - if !containerStatus.Ready { - unreadyContainers = append(unreadyContainers, container.Name) - } - } else { - unknownContainers = append(unknownContainers, container.Name) - } - } - - for _, container := range pod.Spec.Containers { - if containerStatus, ok := podutil.GetContainerStatus(containerStatuses, container.Name); ok { - if !containerStatus.Ready { - unreadyContainers = append(unreadyContainers, container.Name) - } - } else { - unknownContainers = append(unknownContainers, container.Name) - } - } - - // If all containers are known and succeeded, just return PodCompleted. - if podPhase == v1.PodSucceeded && len(unknownContainers) == 0 { - return generateContainersReadyConditionForTerminalPhase(pod, oldPodStatus, podPhase) - } - - // If the pod phase is failed, explicitly set the ready condition to false for containers since they may be in progress of terminating. - if podPhase == v1.PodFailed { - return generateContainersReadyConditionForTerminalPhase(pod, oldPodStatus, podPhase) - } - - // Generate message for containers in unknown condition. - unreadyMessages := []string{} - if len(unknownContainers) > 0 { - unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with unknown status: %s", unknownContainers)) - } - if len(unreadyContainers) > 0 { - unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with unready status: %s", unreadyContainers)) - } - unreadyMessage := strings.Join(unreadyMessages, ", ") - if unreadyMessage != "" { - return v1.PodCondition{ - Type: v1.ContainersReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.ContainersReady), - Status: v1.ConditionFalse, - Reason: ContainersNotReady, - Message: unreadyMessage, - } - } - - return v1.PodCondition{ - Type: v1.ContainersReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.ContainersReady), - Status: v1.ConditionTrue, - } -} - -// GeneratePodReadyCondition returns "Ready" condition of a pod. -// The status of "Ready" condition is "True", if all containers in a pod are ready -// AND all matching conditions specified in the ReadinessGates have status equal to "True". -func GeneratePodReadyCondition(pod *v1.Pod, oldPodStatus *v1.PodStatus, conditions []v1.PodCondition, containerStatuses []v1.ContainerStatus, podPhase v1.PodPhase) v1.PodCondition { - containersReady := GenerateContainersReadyCondition(pod, oldPodStatus, containerStatuses, podPhase) - // If the status of ContainersReady is not True, return the same status, reason and message as ContainersReady. - if containersReady.Status != v1.ConditionTrue { - return v1.PodCondition{ - Type: v1.PodReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodReady), - Status: containersReady.Status, - Reason: containersReady.Reason, - Message: containersReady.Message, - } - } - - // Evaluate corresponding conditions specified in readiness gate - // Generate message if any readiness gate is not satisfied. - unreadyMessages := []string{} - for _, rg := range pod.Spec.ReadinessGates { - _, c := podutil.GetPodConditionFromList(conditions, rg.ConditionType) - if c == nil { - unreadyMessages = append(unreadyMessages, fmt.Sprintf("corresponding condition of pod readiness gate %q does not exist.", string(rg.ConditionType))) - } else if c.Status != v1.ConditionTrue { - unreadyMessages = append(unreadyMessages, fmt.Sprintf("the status of pod readiness gate %q is not \"True\", but %v", string(rg.ConditionType), c.Status)) - } - } - - // Set "Ready" condition to "False" if any readiness gate is not ready. - if len(unreadyMessages) != 0 { - unreadyMessage := strings.Join(unreadyMessages, ", ") - return v1.PodCondition{ - Type: v1.PodReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodReady), - Status: v1.ConditionFalse, - Reason: ReadinessGatesNotReady, - Message: unreadyMessage, - } - } - - return v1.PodCondition{ - Type: v1.PodReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodReady), - Status: v1.ConditionTrue, - } -} - -func isInitContainerInitialized(initContainer *v1.Container, containerStatus *v1.ContainerStatus) bool { - if podutil.IsRestartableInitContainer(initContainer) { - if containerStatus.Started == nil || !*containerStatus.Started { - return false - } - } else { // regular init container - if !containerStatus.Ready { - return false - } - } - return true -} - -// GeneratePodInitializedCondition returns initialized condition if all init containers in a pod are ready, else it -// returns an uninitialized condition. -func GeneratePodInitializedCondition(pod *v1.Pod, oldPodStatus *v1.PodStatus, containerStatuses []v1.ContainerStatus, podPhase v1.PodPhase) v1.PodCondition { - // Find if all containers are ready or not. - if containerStatuses == nil && len(pod.Spec.InitContainers) > 0 { - return v1.PodCondition{ - Type: v1.PodInitialized, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodInitialized), - Status: v1.ConditionFalse, - Reason: UnknownContainerStatuses, - } - } - - unknownContainers := []string{} - incompleteContainers := []string{} - for _, container := range pod.Spec.InitContainers { - containerStatus, ok := podutil.GetContainerStatus(containerStatuses, container.Name) - if !ok { - unknownContainers = append(unknownContainers, container.Name) - continue - } - if !isInitContainerInitialized(&container, &containerStatus) { - incompleteContainers = append(incompleteContainers, container.Name) - } - } - - // If all init containers are known and succeeded, just return PodCompleted. - if podPhase == v1.PodSucceeded && len(unknownContainers) == 0 { - return v1.PodCondition{ - Type: v1.PodInitialized, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodInitialized), - Status: v1.ConditionTrue, - Reason: PodCompleted, - } - } - - // If there is any regular container that has started, then the pod has - // been initialized before. - // This is needed to handle the case where the pod has been initialized but - // the restartable init containers are restarting. - if kubecontainer.HasAnyRegularContainerStarted(&pod.Spec, containerStatuses) { - return v1.PodCondition{ - Type: v1.PodInitialized, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodInitialized), - Status: v1.ConditionTrue, - } - } - - unreadyMessages := make([]string, 0, len(unknownContainers)+len(incompleteContainers)) - if len(unknownContainers) > 0 { - unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with unknown status: %s", unknownContainers)) - } - if len(incompleteContainers) > 0 { - unreadyMessages = append(unreadyMessages, fmt.Sprintf("containers with incomplete status: %s", incompleteContainers)) - } - unreadyMessage := strings.Join(unreadyMessages, ", ") - if unreadyMessage != "" { - return v1.PodCondition{ - Type: v1.PodInitialized, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodInitialized), - Status: v1.ConditionFalse, - Reason: ContainersNotInitialized, - Message: unreadyMessage, - } - } - - return v1.PodCondition{ - Type: v1.PodInitialized, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodInitialized), - Status: v1.ConditionTrue, - } -} - -func GeneratePodReadyToStartContainersCondition(pod *v1.Pod, oldPodStatus *v1.PodStatus, podStatus *kubecontainer.PodStatus) v1.PodCondition { - newSandboxNeeded, _, _ := runtimeutil.PodSandboxChanged(pod, podStatus) - // if a new sandbox does not need to be created for a pod, it indicates that - // a sandbox for the pod with networking configured already exists. - // Otherwise, the kubelet needs to invoke the container runtime to create a - // fresh sandbox and configure networking for the sandbox. - if !newSandboxNeeded { - return v1.PodCondition{ - Type: v1.PodReadyToStartContainers, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodReadyToStartContainers), - Status: v1.ConditionTrue, - } - } - return v1.PodCondition{ - Type: v1.PodReadyToStartContainers, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodReadyToStartContainers), - Status: v1.ConditionFalse, - } -} - -func generateContainersReadyConditionForTerminalPhase(pod *v1.Pod, oldPodStatus *v1.PodStatus, podPhase v1.PodPhase) v1.PodCondition { - condition := v1.PodCondition{ - Type: v1.ContainersReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.ContainersReady), - Status: v1.ConditionFalse, - } - - if podPhase == v1.PodFailed { - condition.Reason = PodFailed - } else if podPhase == v1.PodSucceeded { - condition.Reason = PodCompleted - } - - return condition -} - -func generatePodReadyConditionForTerminalPhase(pod *v1.Pod, oldPodStatus *v1.PodStatus, podPhase v1.PodPhase) v1.PodCondition { - condition := v1.PodCondition{ - Type: v1.PodReady, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(oldPodStatus, pod.Generation, v1.PodReady), - Status: v1.ConditionFalse, - } - - if podPhase == v1.PodFailed { - condition.Reason = PodFailed - } else if podPhase == v1.PodSucceeded { - condition.Reason = PodCompleted - } - - return condition -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go b/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go deleted file mode 100644 index c86bef17f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/status/status_manager.go +++ /dev/null @@ -1,1195 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -//go:generate mockery -package status - -import ( - "context" - "fmt" - "sort" - "strings" - "sync" - "time" - - "github.com/google/go-cmp/cmp" //nolint:depguard - clientset "k8s.io/client-go/kubernetes" - - v1 "k8s.io/api/core/v1" - apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/features" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" - "k8s.io/kubernetes/pkg/kubelet/metrics" - kubetypes "k8s.io/kubernetes/pkg/kubelet/types" - kubeutil "k8s.io/kubernetes/pkg/kubelet/util" - statusutil "k8s.io/kubernetes/pkg/util/pod" -) - -// A wrapper around v1.PodStatus that includes a version to enforce that stale pod statuses are -// not sent to the API server. -type versionedPodStatus struct { - // version is a monotonically increasing version number (per pod). - version uint64 - // Pod name & namespace, for sending updates to API server. - podName string - podNamespace string - // at is the time at which the most recent status update was detected - at time.Time - - // True if the status is generated at the end of SyncTerminatedPod, or after it is completed. - podIsFinished bool - - status v1.PodStatus -} - -// Updates pod statuses in apiserver. Writes only when new status has changed. -// All methods are thread-safe. -type manager struct { - kubeClient clientset.Interface - podManager PodManager - // Map from pod UID to sync status of the corresponding pod. - podStatuses map[types.UID]versionedPodStatus - podResizeConditions map[types.UID]podResizeConditions - podStatusesLock sync.RWMutex - podStatusChannel chan struct{} - // Map from (mirror) pod UID to latest status version successfully sent to the API server. - // apiStatusVersions must only be accessed from the sync thread. - apiStatusVersions map[kubetypes.MirrorPodUID]uint64 - podDeletionSafety PodDeletionSafetyProvider - - podStartupLatencyHelper PodStartupLatencyStateHelper -} - -type podResizeConditions struct { - PodResizePending *v1.PodCondition - PodResizeInProgress *v1.PodCondition -} - -func (prc podResizeConditions) List() []*v1.PodCondition { - var conditions []*v1.PodCondition - if prc.PodResizePending != nil { - conditions = append(conditions, prc.PodResizePending) - } - if prc.PodResizeInProgress != nil { - conditions = append(conditions, prc.PodResizeInProgress) - } - return conditions -} - -// PodManager is the subset of methods the manager needs to observe the actual state of the kubelet. -// See pkg/k8s.io/kubernetes/pkg/kubelet/pod.Manager for method godoc. -type PodManager interface { - GetPodByUID(types.UID) (*v1.Pod, bool) - GetMirrorPodByPod(*v1.Pod) (*v1.Pod, bool) - TranslatePodUID(uid types.UID) kubetypes.ResolvedPodUID - GetUIDTranslations() (podToMirror map[kubetypes.ResolvedPodUID]kubetypes.MirrorPodUID, mirrorToPod map[kubetypes.MirrorPodUID]kubetypes.ResolvedPodUID) -} - -// PodStatusProvider knows how to provide status for a pod. It is intended to be used by other components -// that need to introspect the authoritative status of a pod. The PodStatusProvider represents the actual -// status of a running pod as the kubelet sees it. -type PodStatusProvider interface { - // GetPodStatus returns the cached status for the provided pod UID, as well as whether it - // was a cache hit. - GetPodStatus(uid types.UID) (v1.PodStatus, bool) -} - -// PodDeletionSafetyProvider provides guarantees that a pod can be safely deleted. -type PodDeletionSafetyProvider interface { - // PodCouldHaveRunningContainers returns true if the pod could have running containers. - PodCouldHaveRunningContainers(pod *v1.Pod) bool -} - -type PodStartupLatencyStateHelper interface { - RecordStatusUpdated(pod *v1.Pod) - DeletePodStartupState(podUID types.UID) -} - -// Manager is the Source of truth for kubelet pod status, and should be kept up-to-date with -// the latest v1.PodStatus. It also syncs updates back to the API server. -type Manager interface { - PodStatusProvider - - // Start the API server status sync loop. - Start() - - // SetPodStatus caches updates the cached status for the given pod, and triggers a status update. - SetPodStatus(pod *v1.Pod, status v1.PodStatus) - - // SetContainerReadiness updates the cached container status with the given readiness, and - // triggers a status update. - SetContainerReadiness(podUID types.UID, containerID kubecontainer.ContainerID, ready bool) - - // SetContainerStartup updates the cached container status with the given startup, and - // triggers a status update. - SetContainerStartup(podUID types.UID, containerID kubecontainer.ContainerID, started bool) - - // TerminatePod resets the container status for the provided pod to terminated and triggers - // a status update. - TerminatePod(pod *v1.Pod) - - // RemoveOrphanedStatuses scans the status cache and removes any entries for pods not included in - // the provided podUIDs. - RemoveOrphanedStatuses(podUIDs map[types.UID]bool) - - // GetPodResizeConditions returns cached PodStatus Resize conditions value - GetPodResizeConditions(podUID types.UID) []*v1.PodCondition - - // SetPodResizePendingCondition caches the last PodResizePending condition for the pod. - SetPodResizePendingCondition(podUID types.UID, reason, message string) - - // SetPodResizeInProgressCondition caches the last PodResizeInProgress condition for the pod. - SetPodResizeInProgressCondition(podUID types.UID, reason, message string, allowReasonToBeCleared bool) - - // ClearPodResizePendingCondition clears the PodResizePending condition for the pod from the cache. - ClearPodResizePendingCondition(podUID types.UID) - - // ClearPodResizeInProgressCondition clears the PodResizeInProgress condition for the pod from the cache. - ClearPodResizeInProgressCondition(podUID types.UID) -} - -const syncPeriod = 10 * time.Second - -// NewManager returns a functional Manager. -func NewManager(kubeClient clientset.Interface, podManager PodManager, podDeletionSafety PodDeletionSafetyProvider, podStartupLatencyHelper PodStartupLatencyStateHelper) Manager { - return &manager{ - kubeClient: kubeClient, - podManager: podManager, - podStatuses: make(map[types.UID]versionedPodStatus), - podResizeConditions: make(map[types.UID]podResizeConditions), - podStatusChannel: make(chan struct{}, 1), - apiStatusVersions: make(map[kubetypes.MirrorPodUID]uint64), - podDeletionSafety: podDeletionSafety, - podStartupLatencyHelper: podStartupLatencyHelper, - } -} - -// isPodStatusByKubeletEqual returns true if the given pod statuses are equal when non-kubelet-owned -// pod conditions are excluded. -// This method normalizes the status before comparing so as to make sure that meaningless -// changes will be ignored. -func isPodStatusByKubeletEqual(oldStatus, status *v1.PodStatus) bool { - oldCopy := oldStatus.DeepCopy() - - newConditions := make(map[v1.PodConditionType]*v1.PodCondition, len(status.Conditions)) - oldConditions := make(map[v1.PodConditionType]*v1.PodCondition, len(oldStatus.Conditions)) - for _, c := range status.Conditions { - if kubetypes.PodConditionByKubelet(c.Type) || kubetypes.PodConditionSharedByKubelet(c.Type) { - newConditions[c.Type] = &c - } - } - for _, c := range oldStatus.Conditions { - if kubetypes.PodConditionByKubelet(c.Type) || kubetypes.PodConditionSharedByKubelet(c.Type) { - oldConditions[c.Type] = &c - } - } - - if len(newConditions) != len(oldConditions) { - return false - } - for _, newCondition := range newConditions { - oldCondition := oldConditions[newCondition.Type] - if oldCondition == nil || oldCondition.Status != newCondition.Status || oldCondition.Message != newCondition.Message || oldCondition.Reason != newCondition.Reason { - return false - } - } - - oldCopy.Conditions = status.Conditions - return apiequality.Semantic.DeepEqual(oldCopy, status) -} - -func (m *manager) Start() { - // Don't start the status manager if we don't have a client. This will happen - // on the master, where the kubelet is responsible for bootstrapping the pods - // of the master components. - if m.kubeClient == nil { - klog.InfoS("Kubernetes client is nil, not starting status manager") - return - } - - klog.InfoS("Starting to sync pod status with apiserver") - - //nolint:staticcheck // SA1015 Ticker can leak since this is only called once and doesn't handle termination. - syncTicker := time.NewTicker(syncPeriod).C - - // syncPod and syncBatch share the same go routine to avoid sync races. - go wait.Forever(func() { - for { - select { - case <-m.podStatusChannel: - klog.V(4).InfoS("Syncing updated statuses") - m.syncBatch(false) - case <-syncTicker: - klog.V(4).InfoS("Syncing all statuses") - m.syncBatch(true) - } - } - }, 0) -} - -// GetPodResizeConditions returns the last cached ResizeStatus value. -func (m *manager) GetPodResizeConditions(podUID types.UID) []*v1.PodCondition { - m.podStatusesLock.RLock() - defer m.podStatusesLock.RUnlock() - return m.podResizeConditions[podUID].List() -} - -// SetPodResizePendingCondition caches the last PodResizePending condition for the pod. -func (m *manager) SetPodResizePendingCondition(podUID types.UID, reason, message string) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - - m.podResizeConditions[podUID] = podResizeConditions{ - PodResizePending: updatedPodResizeCondition(v1.PodResizePending, m.podResizeConditions[podUID].PodResizePending, reason, message), - PodResizeInProgress: m.podResizeConditions[podUID].PodResizeInProgress, - } -} - -// SetPodResizeInProgressCondition caches the last PodResizeInProgress condition for the pod. -func (m *manager) SetPodResizeInProgressCondition(podUID types.UID, reason, message string, allowReasonToBeCleared bool) { - oldConditions := m.GetPodResizeConditions(podUID) - - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - - if !allowReasonToBeCleared && reason == "" && message == "" { - // Preserve the old reason and message if there is one. - for _, c := range oldConditions { - if c.Type == v1.PodResizeInProgress { - reason = c.Reason - message = c.Message - } - } - } - - m.podResizeConditions[podUID] = podResizeConditions{ - PodResizeInProgress: updatedPodResizeCondition(v1.PodResizeInProgress, m.podResizeConditions[podUID].PodResizeInProgress, reason, message), - PodResizePending: m.podResizeConditions[podUID].PodResizePending, - } -} - -// ClearPodResizePendingCondition clears the PodResizePending condition for the pod from the cache. -func (m *manager) ClearPodResizePendingCondition(podUID types.UID) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - m.podResizeConditions[podUID] = podResizeConditions{ - PodResizePending: nil, - PodResizeInProgress: m.podResizeConditions[podUID].PodResizeInProgress, - } -} - -// ClearPodResizeInProgressCondition clears the PodResizeInProgress condition for the pod from the cache. -func (m *manager) ClearPodResizeInProgressCondition(podUID types.UID) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - m.podResizeConditions[podUID] = podResizeConditions{ - PodResizePending: m.podResizeConditions[podUID].PodResizePending, - PodResizeInProgress: nil, - } -} - -func (m *manager) GetPodStatus(uid types.UID) (v1.PodStatus, bool) { - m.podStatusesLock.RLock() - defer m.podStatusesLock.RUnlock() - status, ok := m.podStatuses[types.UID(m.podManager.TranslatePodUID(uid))] - return status.status, ok -} - -func (m *manager) SetPodStatus(pod *v1.Pod, status v1.PodStatus) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - - // Make sure we're caching a deep copy. - status = *status.DeepCopy() - - // Set the observedGeneration for this pod status. - status.ObservedGeneration = podutil.GetPodObservedGenerationIfEnabled(pod) - - // Force a status update if deletion timestamp is set. This is necessary - // because if the pod is in the non-running state, the pod worker still - // needs to be able to trigger an update and/or deletion. - m.updateStatusInternal(pod, status, pod.DeletionTimestamp != nil, false) -} - -func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontainer.ContainerID, ready bool) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - - pod, ok := m.podManager.GetPodByUID(podUID) - if !ok { - klog.V(4).InfoS("Pod has been deleted, no need to update readiness", "podUID", string(podUID)) - return - } - - oldStatus, found := m.podStatuses[pod.UID] - if !found { - klog.InfoS("Container readiness changed before pod has synced", - "pod", klog.KObj(pod), - "containerID", containerID.String()) - return - } - - // Find the container to update. - containerStatus, _, ok := findContainerStatus(&oldStatus.status, containerID.String()) - if !ok { - klog.InfoS("Container readiness changed for unknown container", - "pod", klog.KObj(pod), - "containerID", containerID.String()) - return - } - - if containerStatus.Ready == ready { - klog.V(4).InfoS("Container readiness unchanged", - "ready", ready, - "pod", klog.KObj(pod), - "containerID", containerID.String()) - return - } - - // Make sure we're not updating the cached version. - status := *oldStatus.status.DeepCopy() - containerStatus, _, _ = findContainerStatus(&status, containerID.String()) - containerStatus.Ready = ready - - // updateConditionFunc updates the corresponding type of condition - updateConditionFunc := func(conditionType v1.PodConditionType, condition v1.PodCondition) { - conditionIndex := -1 - for i, condition := range status.Conditions { - if condition.Type == conditionType { - conditionIndex = i - break - } - } - if conditionIndex != -1 { - status.Conditions[conditionIndex] = condition - } else { - klog.InfoS("PodStatus missing condition type", "conditionType", conditionType, "status", status) - status.Conditions = append(status.Conditions, condition) - } - } - - allContainerStatuses := append(status.InitContainerStatuses, status.ContainerStatuses...) - updateConditionFunc(v1.PodReady, GeneratePodReadyCondition(pod, &oldStatus.status, status.Conditions, allContainerStatuses, status.Phase)) - updateConditionFunc(v1.ContainersReady, GenerateContainersReadyCondition(pod, &oldStatus.status, allContainerStatuses, status.Phase)) - m.updateStatusInternal(pod, status, false, false) -} - -func (m *manager) SetContainerStartup(podUID types.UID, containerID kubecontainer.ContainerID, started bool) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - - pod, ok := m.podManager.GetPodByUID(podUID) - if !ok { - klog.V(4).InfoS("Pod has been deleted, no need to update startup", "podUID", string(podUID)) - return - } - - oldStatus, found := m.podStatuses[pod.UID] - if !found { - klog.InfoS("Container startup changed before pod has synced", - "pod", klog.KObj(pod), - "containerID", containerID.String()) - return - } - - // Find the container to update. - containerStatus, _, ok := findContainerStatus(&oldStatus.status, containerID.String()) - if !ok { - klog.InfoS("Container startup changed for unknown container", - "pod", klog.KObj(pod), - "containerID", containerID.String()) - return - } - - if containerStatus.Started != nil && *containerStatus.Started == started { - klog.V(4).InfoS("Container startup unchanged", - "pod", klog.KObj(pod), - "containerID", containerID.String()) - return - } - - // Make sure we're not updating the cached version. - status := *oldStatus.status.DeepCopy() - containerStatus, _, _ = findContainerStatus(&status, containerID.String()) - containerStatus.Started = &started - - m.updateStatusInternal(pod, status, false, false) -} - -func findContainerStatus(status *v1.PodStatus, containerID string) (containerStatus *v1.ContainerStatus, init bool, ok bool) { - // Find the container to update. - for i, c := range status.ContainerStatuses { - if c.ContainerID == containerID { - return &status.ContainerStatuses[i], false, true - } - } - - for i, c := range status.InitContainerStatuses { - if c.ContainerID == containerID { - return &status.InitContainerStatuses[i], true, true - } - } - - return nil, false, false - -} - -// TerminatePod ensures that the status of containers is properly defaulted at the end of the pod -// lifecycle. As the Kubelet must reconcile with the container runtime to observe container status -// there is always the possibility we are unable to retrieve one or more container statuses due to -// garbage collection, admin action, or loss of temporary data on a restart. This method ensures -// that any absent container status is treated as a failure so that we do not incorrectly describe -// the pod as successful. If we have not yet initialized the pod in the presence of init containers, -// the init container failure status is sufficient to describe the pod as failing, and we do not need -// to override waiting containers (unless there is evidence the pod previously started those containers). -// It also makes sure that pods are transitioned to a terminal phase (Failed or Succeeded) before -// their deletion. -func (m *manager) TerminatePod(pod *v1.Pod) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - - // ensure that all containers have a terminated state - because we do not know whether the container - // was successful, always report an error - oldStatus := &pod.Status - cachedStatus, isCached := m.podStatuses[pod.UID] - if isCached { - oldStatus = &cachedStatus.status - } - status := *oldStatus.DeepCopy() - - // once a pod has initialized, any missing status is treated as a failure - if hasPodInitialized(pod) { - for i := range status.ContainerStatuses { - if status.ContainerStatuses[i].State.Terminated != nil { - continue - } - status.ContainerStatuses[i].State = v1.ContainerState{ - Terminated: &v1.ContainerStateTerminated{ - Reason: kubecontainer.ContainerReasonStatusUnknown, - Message: "The container could not be located when the pod was terminated", - ExitCode: 137, - }, - } - } - } - - // all but the final suffix of init containers which have no evidence of a container start are - // marked as failed containers - for i := range initializedContainers(status.InitContainerStatuses) { - if status.InitContainerStatuses[i].State.Terminated != nil { - continue - } - status.InitContainerStatuses[i].State = v1.ContainerState{ - Terminated: &v1.ContainerStateTerminated{ - Reason: kubecontainer.ContainerReasonStatusUnknown, - Message: "The container could not be located when the pod was terminated", - ExitCode: 137, - }, - } - } - - // Make sure all pods are transitioned to a terminal phase. - // TODO(#116484): Also assign terminal phase to static an pods. - if !kubetypes.IsStaticPod(pod) { - switch status.Phase { - case v1.PodSucceeded, v1.PodFailed: - // do nothing, already terminal - case v1.PodPending, v1.PodRunning: - if status.Phase == v1.PodRunning && isCached { - klog.InfoS("Terminal running pod should have already been marked as failed, programmer error", "pod", klog.KObj(pod), "podUID", pod.UID) - } - klog.V(3).InfoS("Marking terminal pod as failed", "oldPhase", status.Phase, "pod", klog.KObj(pod), "podUID", pod.UID) - status.Phase = v1.PodFailed - default: - klog.ErrorS(fmt.Errorf("unknown phase: %v", status.Phase), "Unknown phase, programmer error", "pod", klog.KObj(pod), "podUID", pod.UID) - status.Phase = v1.PodFailed - } - } - - klog.V(5).InfoS("TerminatePod calling updateStatusInternal", "pod", klog.KObj(pod), "podUID", pod.UID) - m.updateStatusInternal(pod, status, true, true) -} - -// hasPodInitialized returns true if the pod has no evidence of ever starting a regular container, which -// implies those containers should not be transitioned to terminated status. -func hasPodInitialized(pod *v1.Pod) bool { - // a pod without init containers is always initialized - if len(pod.Spec.InitContainers) == 0 { - return true - } - // if any container has ever moved out of waiting state, the pod has initialized - for _, status := range pod.Status.ContainerStatuses { - if status.LastTerminationState.Terminated != nil || status.State.Waiting == nil { - return true - } - } - // if the last init container has ever completed with a zero exit code, the pod is initialized - if l := len(pod.Status.InitContainerStatuses); l > 0 { - container, ok := kubeutil.GetContainerByIndex(pod.Spec.InitContainers, pod.Status.InitContainerStatuses, l-1) - if !ok { - klog.V(4).InfoS("Mismatch between pod spec and status, likely programmer error", "pod", klog.KObj(pod), "containerName", container.Name) - return false - } - - containerStatus := pod.Status.InitContainerStatuses[l-1] - if podutil.IsRestartableInitContainer(&container) { - if containerStatus.State.Running != nil && - containerStatus.Started != nil && *containerStatus.Started { - return true - } - } else { // regular init container - if state := containerStatus.LastTerminationState; state.Terminated != nil && state.Terminated.ExitCode == 0 { - return true - } - if state := containerStatus.State; state.Terminated != nil && state.Terminated.ExitCode == 0 { - return true - } - } - } - // otherwise the pod has no record of being initialized - return false -} - -// initializedContainers returns all status except for suffix of containers that are in Waiting -// state, which is the set of containers that have attempted to start at least once. If all containers -// are Waiting, the first container is always returned. -func initializedContainers(containers []v1.ContainerStatus) []v1.ContainerStatus { - for i := len(containers) - 1; i >= 0; i-- { - if containers[i].State.Waiting == nil || containers[i].LastTerminationState.Terminated != nil { - return containers[0 : i+1] - } - } - // always return at least one container - if len(containers) > 0 { - return containers[0:1] - } - return nil -} - -// checkContainerStateTransition ensures that no container is trying to transition -// from a terminated to non-terminated state, which is illegal and indicates a -// logical error in the kubelet. -func checkContainerStateTransition(oldStatuses, newStatuses *v1.PodStatus, podSpec *v1.PodSpec) error { - // If we should always restart, containers are allowed to leave the terminated state - if podSpec.RestartPolicy == v1.RestartPolicyAlways { - return nil - } - for _, oldStatus := range oldStatuses.ContainerStatuses { - // Skip any container that wasn't terminated - if oldStatus.State.Terminated == nil { - continue - } - // Skip any container that failed but is allowed to restart - if oldStatus.State.Terminated.ExitCode != 0 && podSpec.RestartPolicy == v1.RestartPolicyOnFailure { - continue - } - for _, newStatus := range newStatuses.ContainerStatuses { - if oldStatus.Name == newStatus.Name && newStatus.State.Terminated == nil { - return fmt.Errorf("terminated container %v attempted illegal transition to non-terminated state", newStatus.Name) - } - } - } - - for i, oldStatus := range oldStatuses.InitContainerStatuses { - initContainer, ok := kubeutil.GetContainerByIndex(podSpec.InitContainers, oldStatuses.InitContainerStatuses, i) - if !ok { - return fmt.Errorf("found mismatch between pod spec and status, container: %v", oldStatus.Name) - } - // Skip any restartable init container as it always is allowed to restart - if podutil.IsRestartableInitContainer(&initContainer) { - continue - } - // Skip any container that wasn't terminated - if oldStatus.State.Terminated == nil { - continue - } - // Skip any container that failed but is allowed to restart - if oldStatus.State.Terminated.ExitCode != 0 && podSpec.RestartPolicy == v1.RestartPolicyOnFailure { - continue - } - for _, newStatus := range newStatuses.InitContainerStatuses { - if oldStatus.Name == newStatus.Name && newStatus.State.Terminated == nil { - return fmt.Errorf("terminated init container %v attempted illegal transition to non-terminated state", newStatus.Name) - } - } - } - return nil -} - -// updateStatusInternal updates the internal status cache, and queues an update to the api server if -// necessary. -// This method IS NOT THREAD SAFE and must be called from a locked function. -func (m *manager) updateStatusInternal(pod *v1.Pod, status v1.PodStatus, forceUpdate, podIsFinished bool) { - var oldStatus v1.PodStatus - cachedStatus, isCached := m.podStatuses[pod.UID] - if isCached { - oldStatus = cachedStatus.status - // TODO(#116484): Also assign terminal phase to static pods. - if !kubetypes.IsStaticPod(pod) { - if cachedStatus.podIsFinished && !podIsFinished { - klog.InfoS("Got unexpected podIsFinished=false, while podIsFinished=true in status cache, programmer error.", "pod", klog.KObj(pod)) - podIsFinished = true - } - } - } else if mirrorPod, ok := m.podManager.GetMirrorPodByPod(pod); ok { - oldStatus = mirrorPod.Status - } else { - oldStatus = pod.Status - } - - // Check for illegal state transition in containers - if err := checkContainerStateTransition(&oldStatus, &status, &pod.Spec); err != nil { - klog.ErrorS(err, "Status update on pod aborted", "pod", klog.KObj(pod)) - return - } - - // Set ContainersReadyCondition.LastTransitionTime. - updateLastTransitionTime(&status, &oldStatus, v1.ContainersReady) - - // Set ReadyCondition.LastTransitionTime. - updateLastTransitionTime(&status, &oldStatus, v1.PodReady) - - // Set InitializedCondition.LastTransitionTime. - updateLastTransitionTime(&status, &oldStatus, v1.PodInitialized) - - // Set PodReadyToStartContainersCondition.LastTransitionTime. - updateLastTransitionTime(&status, &oldStatus, v1.PodReadyToStartContainers) - - // Set PodScheduledCondition.LastTransitionTime. - updateLastTransitionTime(&status, &oldStatus, v1.PodScheduled) - - // Set DisruptionTarget.LastTransitionTime. - updateLastTransitionTime(&status, &oldStatus, v1.DisruptionTarget) - - // ensure that the start time does not change across updates. - if oldStatus.StartTime != nil && !oldStatus.StartTime.IsZero() { - status.StartTime = oldStatus.StartTime - } else if status.StartTime.IsZero() { - // if the status has no start time, we need to set an initial time - now := metav1.Now() - status.StartTime = &now - } - - // prevent sending unnecessary patches - if oldStatus.ObservedGeneration > status.ObservedGeneration { - status.ObservedGeneration = oldStatus.ObservedGeneration - } - - normalizeStatus(pod, &status) - - // Perform some more extensive logging of container termination state to assist in - // debugging production races (generally not needed). - if klogV := klog.V(5); klogV.Enabled() { - var containers []string - for _, s := range append(append([]v1.ContainerStatus(nil), status.InitContainerStatuses...), status.ContainerStatuses...) { - var current, previous string - switch { - case s.State.Running != nil: - current = "running" - case s.State.Waiting != nil: - current = "waiting" - case s.State.Terminated != nil: - current = fmt.Sprintf("terminated=%d", s.State.Terminated.ExitCode) - default: - current = "unknown" - } - switch { - case s.LastTerminationState.Running != nil: - previous = "running" - case s.LastTerminationState.Waiting != nil: - previous = "waiting" - case s.LastTerminationState.Terminated != nil: - previous = fmt.Sprintf("terminated=%d", s.LastTerminationState.Terminated.ExitCode) - default: - previous = "" - } - containers = append(containers, fmt.Sprintf("(%s state=%s previous=%s)", s.Name, current, previous)) - } - sort.Strings(containers) - klogV.InfoS("updateStatusInternal", "version", cachedStatus.version+1, "podIsFinished", podIsFinished, "pod", klog.KObj(pod), "podUID", pod.UID, "containers", strings.Join(containers, " ")) - } - - // The intent here is to prevent concurrent updates to a pod's status from - // clobbering each other so the phase of a pod progresses monotonically. - if isCached && isPodStatusByKubeletEqual(&cachedStatus.status, &status) && !forceUpdate { - klog.V(3).InfoS("Ignoring same status for pod", "pod", klog.KObj(pod), "status", status) - return - } - - newStatus := versionedPodStatus{ - status: status, - version: cachedStatus.version + 1, - podName: pod.Name, - podNamespace: pod.Namespace, - podIsFinished: podIsFinished, - } - - // Multiple status updates can be generated before we update the API server, - // so we track the time from the first status update until we retire it to - // the API. - if cachedStatus.at.IsZero() { - newStatus.at = time.Now() - } else { - newStatus.at = cachedStatus.at - } - - m.podStatuses[pod.UID] = newStatus - - select { - case m.podStatusChannel <- struct{}{}: - default: - // there's already a status update pending - } -} - -// updateLastTransitionTime updates the LastTransitionTime of a pod condition. -func updateLastTransitionTime(status, oldStatus *v1.PodStatus, conditionType v1.PodConditionType) { - _, condition := podutil.GetPodCondition(status, conditionType) - if condition == nil { - return - } - // Need to set LastTransitionTime. - lastTransitionTime := metav1.Now() - _, oldCondition := podutil.GetPodCondition(oldStatus, conditionType) - if oldCondition != nil && condition.Status == oldCondition.Status { - lastTransitionTime = oldCondition.LastTransitionTime - } - condition.LastTransitionTime = lastTransitionTime -} - -// deletePodStatus simply removes the given pod from the status cache. -func (m *manager) deletePodStatus(uid types.UID) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - delete(m.podStatuses, uid) - m.podStartupLatencyHelper.DeletePodStartupState(uid) - if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { - delete(m.podResizeConditions, uid) - } -} - -// TODO(filipg): It'd be cleaner if we can do this without signal from user. -func (m *manager) RemoveOrphanedStatuses(podUIDs map[types.UID]bool) { - m.podStatusesLock.Lock() - defer m.podStatusesLock.Unlock() - for key := range m.podStatuses { - if _, ok := podUIDs[key]; !ok { - klog.V(5).InfoS("Removing pod from status map.", "podUID", key) - delete(m.podStatuses, key) - if utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) { - delete(m.podResizeConditions, key) - } - } - } -} - -// syncBatch syncs pods statuses with the apiserver. Returns the number of syncs -// attempted for testing. -func (m *manager) syncBatch(all bool) int { - type podSync struct { - podUID types.UID - statusUID kubetypes.MirrorPodUID - status versionedPodStatus - } - - var updatedStatuses []podSync - podToMirror, mirrorToPod := m.podManager.GetUIDTranslations() - func() { // Critical section - m.podStatusesLock.RLock() - defer m.podStatusesLock.RUnlock() - - // Clean up orphaned versions. - if all { - for uid := range m.apiStatusVersions { - _, hasPod := m.podStatuses[types.UID(uid)] - _, hasMirror := mirrorToPod[uid] - if !hasPod && !hasMirror { - delete(m.apiStatusVersions, uid) - } - } - } - - // Decide which pods need status updates. - for uid, status := range m.podStatuses { - // translate the pod UID (source) to the status UID (API pod) - - // static pods are identified in source by pod UID but tracked in the - // API via the uid of the mirror pod - uidOfStatus := kubetypes.MirrorPodUID(uid) - if mirrorUID, ok := podToMirror[kubetypes.ResolvedPodUID(uid)]; ok { - if mirrorUID == "" { - klog.V(5).InfoS("Static pod does not have a corresponding mirror pod; skipping", - "podUID", uid, - "pod", klog.KRef(status.podNamespace, status.podName)) - continue - } - uidOfStatus = mirrorUID - } - - // if a new status update has been delivered, trigger an update, otherwise the - // pod can wait for the next bulk check (which performs reconciliation as well) - if !all { - if m.apiStatusVersions[uidOfStatus] >= status.version { - continue - } - updatedStatuses = append(updatedStatuses, podSync{uid, uidOfStatus, status}) - continue - } - - // Ensure that any new status, or mismatched status, or pod that is ready for - // deletion gets updated. If a status update fails we retry the next time any - // other pod is updated. - if m.needsUpdate(types.UID(uidOfStatus), status) { - updatedStatuses = append(updatedStatuses, podSync{uid, uidOfStatus, status}) - } else if m.needsReconcile(uid, status.status) { - // Delete the apiStatusVersions here to force an update on the pod status - // In most cases the deleted apiStatusVersions here should be filled - // soon after the following syncPod() [If the syncPod() sync an update - // successfully]. - delete(m.apiStatusVersions, uidOfStatus) - updatedStatuses = append(updatedStatuses, podSync{uid, uidOfStatus, status}) - } - } - }() - - for _, update := range updatedStatuses { - klog.V(5).InfoS("Sync pod status", "podUID", update.podUID, "statusUID", update.statusUID, "version", update.status.version) - m.syncPod(update.podUID, update.status) - } - - return len(updatedStatuses) -} - -// syncPod syncs the given status with the API server. The caller must not hold the status lock. -func (m *manager) syncPod(uid types.UID, status versionedPodStatus) { - // TODO: make me easier to express from client code - pod, err := m.kubeClient.CoreV1().Pods(status.podNamespace).Get(context.TODO(), status.podName, metav1.GetOptions{}) - if errors.IsNotFound(err) { - klog.V(3).InfoS("Pod does not exist on the server", - "podUID", uid, - "pod", klog.KRef(status.podNamespace, status.podName)) - // If the Pod is deleted the status will be cleared in - // RemoveOrphanedStatuses, so we just ignore the update here. - return - } - if err != nil { - klog.InfoS("Failed to get status for pod", - "podUID", uid, - "pod", klog.KRef(status.podNamespace, status.podName), - "err", err) - return - } - - translatedUID := m.podManager.TranslatePodUID(pod.UID) - // Type convert original uid just for the purpose of comparison. - if len(translatedUID) > 0 && translatedUID != kubetypes.ResolvedPodUID(uid) { - klog.V(2).InfoS("Pod was deleted and then recreated, skipping status update", - "pod", klog.KObj(pod), - "oldPodUID", uid, - "podUID", translatedUID) - m.deletePodStatus(uid) - return - } - - mergedStatus := mergePodStatus(pod, pod.Status, status.status, m.podDeletionSafety.PodCouldHaveRunningContainers(pod)) - - newPod, patchBytes, unchanged, err := statusutil.PatchPodStatus(context.TODO(), m.kubeClient, pod.Namespace, pod.Name, pod.UID, pod.Status, mergedStatus) - klog.V(3).InfoS("Patch status for pod", "pod", klog.KObj(pod), "podUID", uid, "patch", string(patchBytes)) - - if err != nil { - klog.InfoS("Failed to update status for pod", "pod", klog.KObj(pod), "err", err) - return - } - if unchanged { - klog.V(3).InfoS("Status for pod is up-to-date", "pod", klog.KObj(pod), "statusVersion", status.version) - } else { - klog.V(3).InfoS("Status for pod updated successfully", "pod", klog.KObj(pod), "statusVersion", status.version, "status", mergedStatus) - pod = newPod - // We pass a new object (result of API call which contains updated ResourceVersion) - m.podStartupLatencyHelper.RecordStatusUpdated(pod) - } - - // measure how long the status update took to propagate from generation to update on the server - if status.at.IsZero() { - klog.V(3).InfoS("Pod had no status time set", "pod", klog.KObj(pod), "podUID", uid, "version", status.version) - } else { - duration := time.Since(status.at).Truncate(time.Millisecond) - metrics.PodStatusSyncDuration.Observe(duration.Seconds()) - } - - m.apiStatusVersions[kubetypes.MirrorPodUID(pod.UID)] = status.version - - // We don't handle graceful deletion of mirror pods. - if m.canBeDeleted(pod, status.status, status.podIsFinished) { - deleteOptions := metav1.DeleteOptions{ - GracePeriodSeconds: new(int64), - // Use the pod UID as the precondition for deletion to prevent deleting a - // newly created pod with the same name and namespace. - Preconditions: metav1.NewUIDPreconditions(string(pod.UID)), - } - err = m.kubeClient.CoreV1().Pods(pod.Namespace).Delete(context.TODO(), pod.Name, deleteOptions) - if err != nil { - klog.InfoS("Failed to delete status for pod", "pod", klog.KObj(pod), "err", err) - return - } - klog.V(3).InfoS("Pod fully terminated and removed from etcd", "pod", klog.KObj(pod)) - m.deletePodStatus(uid) - } -} - -// needsUpdate returns whether the status is stale for the given pod UID. -// This method is not thread safe, and must only be accessed by the sync thread. -func (m *manager) needsUpdate(uid types.UID, status versionedPodStatus) bool { - latest, ok := m.apiStatusVersions[kubetypes.MirrorPodUID(uid)] - if !ok || latest < status.version { - return true - } - pod, ok := m.podManager.GetPodByUID(uid) - if !ok { - return false - } - return m.canBeDeleted(pod, status.status, status.podIsFinished) -} - -func (m *manager) canBeDeleted(pod *v1.Pod, status v1.PodStatus, podIsFinished bool) bool { - if pod.DeletionTimestamp == nil || kubetypes.IsMirrorPod(pod) { - return false - } - // Delay deletion of pods until the phase is terminal, based on pod.Status - // which comes from pod manager. - if !podutil.IsPodPhaseTerminal(pod.Status.Phase) { - // For debugging purposes we also log the kubelet's local phase, when the deletion is delayed. - klog.V(3).InfoS("Delaying pod deletion as the phase is non-terminal", "phase", pod.Status.Phase, "localPhase", status.Phase, "pod", klog.KObj(pod), "podUID", pod.UID) - return false - } - // If this is an update completing pod termination then we know the pod termination is finished. - if podIsFinished { - klog.V(3).InfoS("The pod termination is finished as SyncTerminatedPod completes its execution", "phase", pod.Status.Phase, "localPhase", status.Phase, "pod", klog.KObj(pod), "podUID", pod.UID) - return true - } - return false -} - -// needsReconcile compares the given status with the status in the pod manager (which -// in fact comes from apiserver), returns whether the status needs to be reconciled with -// the apiserver. Now when pod status is inconsistent between apiserver and kubelet, -// kubelet should forcibly send an update to reconcile the inconsistence, because kubelet -// should be the source of truth of pod status. -// NOTE(random-liu): It's simpler to pass in mirror pod uid and get mirror pod by uid, but -// now the pod manager only supports getting mirror pod by static pod, so we have to pass -// static pod uid here. -// TODO(random-liu): Simplify the logic when mirror pod manager is added. -func (m *manager) needsReconcile(uid types.UID, status v1.PodStatus) bool { - // The pod could be a static pod, so we should translate first. - pod, ok := m.podManager.GetPodByUID(uid) - if !ok { - klog.V(4).InfoS("Pod has been deleted, no need to reconcile", "podUID", string(uid)) - return false - } - // If the pod is a static pod, we should check its mirror pod, because only status in mirror pod is meaningful to us. - if kubetypes.IsStaticPod(pod) { - mirrorPod, ok := m.podManager.GetMirrorPodByPod(pod) - if !ok { - klog.V(4).InfoS("Static pod has no corresponding mirror pod, no need to reconcile", "pod", klog.KObj(pod)) - return false - } - pod = mirrorPod - } - - podStatus := pod.Status.DeepCopy() - normalizeStatus(pod, podStatus) - - if isPodStatusByKubeletEqual(podStatus, &status) { - // If the status from the source is the same with the cached status, - // reconcile is not needed. Just return. - return false - } - klog.V(3).InfoS("Pod status is inconsistent with cached status for pod, a reconciliation should be triggered", - "pod", klog.KObj(pod), - "statusDiff", cmp.Diff(podStatus, &status)) - - return true -} - -// normalizeStatus normalizes nanosecond precision timestamps in podStatus -// down to second precision (*RFC339NANO* -> *RFC3339*). This must be done -// before comparing podStatus to the status returned by apiserver because -// apiserver does not support RFC339NANO. -// Related issue #15262/PR #15263 to move apiserver to RFC339NANO is closed. -func normalizeStatus(pod *v1.Pod, status *v1.PodStatus) *v1.PodStatus { - bytesPerStatus := kubecontainer.MaxPodTerminationMessageLogLength - if containers := len(pod.Spec.Containers) + len(pod.Spec.InitContainers) + len(pod.Spec.EphemeralContainers); containers > 0 { - bytesPerStatus = bytesPerStatus / containers - } - normalizeTimeStamp := func(t *metav1.Time) { - *t = t.Rfc3339Copy() - } - normalizeContainerState := func(c *v1.ContainerState) { - if c.Running != nil { - normalizeTimeStamp(&c.Running.StartedAt) - } - if c.Terminated != nil { - normalizeTimeStamp(&c.Terminated.StartedAt) - normalizeTimeStamp(&c.Terminated.FinishedAt) - if len(c.Terminated.Message) > bytesPerStatus { - c.Terminated.Message = c.Terminated.Message[:bytesPerStatus] - } - } - } - - if status.StartTime != nil { - normalizeTimeStamp(status.StartTime) - } - for i := range status.Conditions { - condition := &status.Conditions[i] - normalizeTimeStamp(&condition.LastProbeTime) - normalizeTimeStamp(&condition.LastTransitionTime) - } - - normalizeContainerStatuses := func(containerStatuses []v1.ContainerStatus) { - for i := range containerStatuses { - cstatus := &containerStatuses[i] - normalizeContainerState(&cstatus.State) - normalizeContainerState(&cstatus.LastTerminationState) - } - } - - normalizeContainerStatuses(status.ContainerStatuses) - sort.Sort(kubetypes.SortedContainerStatuses(status.ContainerStatuses)) - - normalizeContainerStatuses(status.InitContainerStatuses) - kubetypes.SortInitContainerStatuses(pod, status.InitContainerStatuses) - - normalizeContainerStatuses(status.EphemeralContainerStatuses) - sort.Sort(kubetypes.SortedContainerStatuses(status.EphemeralContainerStatuses)) - - return status -} - -// mergePodStatus merges oldPodStatus and newPodStatus to preserve where pod conditions -// not owned by kubelet and to ensure terminal phase transition only happens after all -// running containers have terminated. This method does not modify the old status. -func mergePodStatus(pod *v1.Pod, oldPodStatus, newPodStatus v1.PodStatus, couldHaveRunningContainers bool) v1.PodStatus { - podConditions := make([]v1.PodCondition, 0, len(oldPodStatus.Conditions)+len(newPodStatus.Conditions)) - - for _, c := range oldPodStatus.Conditions { - if !kubetypes.PodConditionByKubelet(c.Type) { - podConditions = append(podConditions, c) - } - } - - transitioningToTerminalPhase := !podutil.IsPodPhaseTerminal(oldPodStatus.Phase) && podutil.IsPodPhaseTerminal(newPodStatus.Phase) - - for _, c := range newPodStatus.Conditions { - if kubetypes.PodConditionByKubelet(c.Type) { - podConditions = append(podConditions, c) - } else if kubetypes.PodConditionSharedByKubelet(c.Type) { - // we replace or append all the "shared by kubelet" conditions - if c.Type == v1.DisruptionTarget { - // guard the update of the DisruptionTarget condition with a check to ensure - // it will only be sent once all containers have terminated and the phase - // is terminal. This avoids sending an unnecessary patch request to add - // the condition if the actual status phase transition is delayed. - if transitioningToTerminalPhase && !couldHaveRunningContainers { - // update the LastTransitionTime again here because the older transition - // time set in updateStatusInternal is likely stale as sending of - // the condition was delayed until all pod's containers have terminated. - updateLastTransitionTime(&newPodStatus, &oldPodStatus, c.Type) - if _, c := podutil.GetPodConditionFromList(newPodStatus.Conditions, c.Type); c != nil { - // for shared conditions we update or append in podConditions - podConditions = statusutil.ReplaceOrAppendPodCondition(podConditions, c) - } - } - } - } - } - newPodStatus.Conditions = podConditions - - // ResourceClaimStatuses is not owned and not modified by kubelet. - newPodStatus.ResourceClaimStatuses = oldPodStatus.ResourceClaimStatuses - - // Delay transitioning a pod to a terminal status unless the pod is actually terminal. - // The Kubelet should never transition a pod to terminal status that could have running - // containers and thus actively be leveraging exclusive resources. Note that resources - // like volumes are reconciled by a subsystem in the Kubelet and will converge if a new - // pod reuses an exclusive resource (unmount -> free -> mount), which means we do not - // need wait for those resources to be detached by the Kubelet. In general, resources - // the Kubelet exclusively owns must be released prior to a pod being reported terminal, - // while resources that have participanting components above the API use the pod's - // transition to a terminal phase (or full deletion) to release those resources. - if transitioningToTerminalPhase { - if couldHaveRunningContainers { - newPodStatus.Phase = oldPodStatus.Phase - newPodStatus.Reason = oldPodStatus.Reason - newPodStatus.Message = oldPodStatus.Message - } - } - - // If the new phase is terminal, explicitly set the ready condition to false for v1.PodReady and v1.ContainersReady. - // It may take some time for kubelet to reconcile the ready condition, so explicitly set ready conditions to false if the phase is terminal. - // This is done to ensure kubelet does not report a status update with terminal pod phase and ready=true. - // See https://issues.k8s.io/108594 for more details. - if podutil.IsPodPhaseTerminal(newPodStatus.Phase) { - if podutil.IsPodReadyConditionTrue(newPodStatus) || podutil.IsContainersReadyConditionTrue(newPodStatus) { - containersReadyCondition := generateContainersReadyConditionForTerminalPhase(pod, &oldPodStatus, newPodStatus.Phase) - podutil.UpdatePodCondition(&newPodStatus, &containersReadyCondition) - - podReadyCondition := generatePodReadyConditionForTerminalPhase(pod, &oldPodStatus, newPodStatus.Phase) - podutil.UpdatePodCondition(&newPodStatus, &podReadyCondition) - } - } - - return newPodStatus -} - -// NeedToReconcilePodReadiness returns if the pod "Ready" condition need to be reconcile -func NeedToReconcilePodReadiness(pod *v1.Pod) bool { - if len(pod.Spec.ReadinessGates) == 0 { - return false - } - podReadyCondition := GeneratePodReadyCondition(pod, &pod.Status, pod.Status.Conditions, pod.Status.ContainerStatuses, pod.Status.Phase) - i, curCondition := podutil.GetPodConditionFromList(pod.Status.Conditions, v1.PodReady) - // Only reconcile if "Ready" condition is present and Status or Message is not expected - if i >= 0 && (curCondition.Status != podReadyCondition.Status || curCondition.Message != podReadyCondition.Message) { - return true - } - return false -} - -func updatedPodResizeCondition(conditionType v1.PodConditionType, oldCondition *v1.PodCondition, reason, message string) *v1.PodCondition { - now := metav1.NewTime(time.Now()) - var lastTransitionTime metav1.Time - if oldCondition == nil || oldCondition.Reason != reason { - lastTransitionTime = now - } else { - lastTransitionTime = oldCondition.LastTransitionTime - } - - return &v1.PodCondition{ - Type: conditionType, - Status: v1.ConditionTrue, - LastProbeTime: now, - LastTransitionTime: lastTransitionTime, - Reason: reason, - Message: message, - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go b/vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go deleted file mode 100644 index 791052dbb..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/types/constants.go +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package types - -const ( - // ResolvConfDefault is the system default DNS resolver configuration. - ResolvConfDefault = "/etc/resolv.conf" -) - -// User visible keys for managing node allocatable enforcement on the node. -const ( - NodeAllocatableEnforcementKey = "pods" - SystemReservedEnforcementKey = "system-reserved" - SystemReservedCompressibleEnforcementKey = "system-reserved-compressible" - KubeReservedEnforcementKey = "kube-reserved" - KubeReservedCompressibleEnforcementKey = "kube-reserved-compressible" - NodeAllocatableNoneKey = "none" -) - -// SwapBehavior types -type SwapBehavior string - -const ( - LimitedSwap SwapBehavior = "LimitedSwap" - NoSwap SwapBehavior = "NoSwap" -) diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/types/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/types/doc.go deleted file mode 100644 index 9227a16ef..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/types/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package types contains common types in the Kubelet. -package types diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_status.go b/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_status.go deleted file mode 100644 index 24612e40d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_status.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package types - -import ( - v1 "k8s.io/api/core/v1" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" -) - -// PodConditionsByKubelet is the list of pod conditions owned by kubelet -var PodConditionsByKubelet = []v1.PodConditionType{ - v1.PodScheduled, - v1.PodReady, - v1.PodInitialized, - v1.ContainersReady, - v1.PodResizeInProgress, - v1.PodResizePending, -} - -// PodConditionByKubelet returns if the pod condition type is owned by kubelet -func PodConditionByKubelet(conditionType v1.PodConditionType) bool { - for _, c := range PodConditionsByKubelet { - if c == conditionType { - return true - } - } - if utilfeature.DefaultFeatureGate.Enabled(features.PodReadyToStartContainersCondition) { - if conditionType == v1.PodReadyToStartContainers { - return true - } - } - return false -} - -// PodConditionSharedByKubelet returns if the pod condition type is shared by kubelet -func PodConditionSharedByKubelet(conditionType v1.PodConditionType) bool { - return conditionType == v1.DisruptionTarget -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go b/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go deleted file mode 100644 index ee4bd58c7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/types/pod_update.go +++ /dev/null @@ -1,206 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package types - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/apis/scheduling" -) - -// Annotation keys for annotations used in this package. -const ( - ConfigSourceAnnotationKey = "kubernetes.io/config.source" - ConfigMirrorAnnotationKey = v1.MirrorPodAnnotationKey - ConfigFirstSeenAnnotationKey = "kubernetes.io/config.seen" - ConfigHashAnnotationKey = "kubernetes.io/config.hash" -) - -// PodOperation defines what changes will be made on a pod configuration. -type PodOperation int - -// These constants identify the PodOperations that can be made on a pod configuration. -const ( - // SET is the current pod configuration. - SET PodOperation = iota - // ADD signifies pods that are new to this source. - ADD - // DELETE signifies pods that are gracefully deleted from this source. - DELETE - // REMOVE signifies pods that have been removed from this source. - REMOVE - // UPDATE signifies pods have been updated in this source. - UPDATE - // RECONCILE signifies pods that have unexpected status in this source, - // kubelet should reconcile status with this source. - RECONCILE -) - -// These constants identify the sources of pods. -const ( - // Filesource idenitified updates from a file. - FileSource = "file" - // HTTPSource identifies updates from querying a web page. - HTTPSource = "http" - // ApiserverSource identifies updates from Kubernetes API Server. - ApiserverSource = "api" - // AllSource identifies updates from all sources. - AllSource = "*" -) - -// NamespaceDefault is a string representing the default namespace. -const NamespaceDefault = metav1.NamespaceDefault - -// PodUpdate defines an operation sent on the channel. You can add or remove single services by -// sending an array of size one and Op == ADD|REMOVE (with REMOVE, only the ID is required). -// For setting the state of the system to a given state for this source configuration, set -// Pods as desired and Op to SET, which will reset the system state to that specified in this -// operation for this source channel. To remove all pods, set Pods to empty object and Op to SET. -// -// Additionally, Pods should never be nil - it should always point to an empty slice. While -// functionally similar, this helps our unit tests properly check that the correct PodUpdates -// are generated. -type PodUpdate struct { - Pods []*v1.Pod - Op PodOperation - Source string -} - -// GetValidatedSources gets all validated sources from the specified sources. -func GetValidatedSources(sources []string) ([]string, error) { - validated := make([]string, 0, len(sources)) - for _, source := range sources { - switch source { - case AllSource: - return []string{FileSource, HTTPSource, ApiserverSource}, nil - case FileSource, HTTPSource, ApiserverSource: - validated = append(validated, source) - case "": - // Skip - default: - return []string{}, fmt.Errorf("unknown pod source %q", source) - } - } - return validated, nil -} - -// GetPodSource returns the source of the pod based on the annotation. -func GetPodSource(pod *v1.Pod) (string, error) { - if pod.Annotations != nil { - if source, ok := pod.Annotations[ConfigSourceAnnotationKey]; ok { - return source, nil - } - } - return "", fmt.Errorf("cannot get source of pod %q", pod.UID) -} - -// SyncPodType classifies pod updates, eg: create, update. -type SyncPodType int - -const ( - // SyncPodSync is when the pod is synced to ensure desired state - SyncPodSync SyncPodType = iota - // SyncPodUpdate is when the pod is updated from source - SyncPodUpdate - // SyncPodCreate is when the pod is created from source - SyncPodCreate - // SyncPodKill is when the pod should have no running containers. A pod stopped in this way could be - // restarted in the future due config changes. - SyncPodKill -) - -func (sp SyncPodType) String() string { - switch sp { - case SyncPodCreate: - return "create" - case SyncPodUpdate: - return "update" - case SyncPodSync: - return "sync" - case SyncPodKill: - return "kill" - default: - return "unknown" - } -} - -// IsMirrorPod returns true if the passed Pod is a Mirror Pod. -func IsMirrorPod(pod *v1.Pod) bool { - if pod.Annotations == nil { - return false - } - _, ok := pod.Annotations[ConfigMirrorAnnotationKey] - return ok -} - -// IsStaticPod returns true if the pod is a static pod. -func IsStaticPod(pod *v1.Pod) bool { - source, err := GetPodSource(pod) - return err == nil && source != ApiserverSource -} - -// IsCriticalPod returns true if pod's priority is greater than or equal to SystemCriticalPriority. -func IsCriticalPod(pod *v1.Pod) bool { - if IsStaticPod(pod) { - return true - } - if IsMirrorPod(pod) { - return true - } - if pod.Spec.Priority != nil && IsCriticalPodBasedOnPriority(*pod.Spec.Priority) { - return true - } - return false -} - -// Preemptable returns true if preemptor pod can preempt preemptee pod -// if preemptee is not critical or if preemptor's priority is greater than preemptee's priority -func Preemptable(preemptor, preemptee *v1.Pod) bool { - if IsCriticalPod(preemptor) && !IsCriticalPod(preemptee) { - return true - } - if (preemptor != nil && preemptor.Spec.Priority != nil) && - (preemptee != nil && preemptee.Spec.Priority != nil) { - return *(preemptor.Spec.Priority) > *(preemptee.Spec.Priority) - } - - return false -} - -// IsCriticalPodBasedOnPriority checks if the given pod is a critical pod based on priority resolved from pod Spec. -func IsCriticalPodBasedOnPriority(priority int32) bool { - return priority >= scheduling.SystemCriticalPriority -} - -// IsNodeCriticalPod checks if the given pod is a system-node-critical -func IsNodeCriticalPod(pod *v1.Pod) bool { - return IsCriticalPod(pod) && (pod.Spec.PriorityClassName == scheduling.SystemNodeCritical) -} - -// HasRestartableInitContainer returns true if the pod has any restartable init -// container -func HasRestartableInitContainer(pod *v1.Pod) bool { - for _, container := range pod.Spec.InitContainers { - if podutil.IsRestartableInitContainer(&container) { - return true - } - } - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/types/types.go b/vendor/k8s.io/kubernetes/pkg/kubelet/types/types.go deleted file mode 100644 index 1cc6ceaef..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/types/types.go +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package types - -import ( - "net/http" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/cri-client/pkg/logs" -) - -// TODO: Reconcile custom types in kubelet/types and this subpackage - -// HTTPDoer encapsulates http.Do functionality -type HTTPDoer interface { - Do(req *http.Request) (*http.Response, error) -} - -// Timestamp wraps around time.Time and offers utilities to format and parse -// the time using RFC3339Nano -type Timestamp struct { - time time.Time -} - -// NewTimestamp returns a Timestamp object using the current time. -func NewTimestamp() *Timestamp { - return &Timestamp{time.Now()} -} - -// ConvertToTimestamp takes a string, parses it using the RFC3339NanoLenient layout, -// and converts it to a Timestamp object. -func ConvertToTimestamp(timeString string) *Timestamp { - parsed, _ := time.Parse(logs.RFC3339NanoLenient, timeString) - return &Timestamp{parsed} -} - -// Get returns the time as time.Time. -func (t *Timestamp) Get() time.Time { - return t.time -} - -// GetString returns the time in the string format using the RFC3339NanoFixed -// layout. -func (t *Timestamp) GetString() string { - return t.time.Format(logs.RFC3339NanoFixed) -} - -// SortedContainerStatuses is a type to help sort container statuses based on container names. -type SortedContainerStatuses []v1.ContainerStatus - -func (s SortedContainerStatuses) Len() int { return len(s) } -func (s SortedContainerStatuses) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -func (s SortedContainerStatuses) Less(i, j int) bool { - return s[i].Name < s[j].Name -} - -// SortInitContainerStatuses ensures that statuses are in the order that their -// init container appears in the pod spec. The function assumes there are no -// duplicate names in the statuses. -func SortInitContainerStatuses(p *v1.Pod, statuses []v1.ContainerStatus) { - containers := p.Spec.InitContainers - current := 0 - for _, container := range containers { - for j := current; j < len(statuses); j++ { - if container.Name == statuses[j].Name { - statuses[current], statuses[j] = statuses[j], statuses[current] - current++ - break - } - } - } -} - -// SortStatusesOfInitContainers returns the statuses of InitContainers of pod p, -// in the order that they appear in its spec. -func SortStatusesOfInitContainers(p *v1.Pod, statusMap map[string]*v1.ContainerStatus) []v1.ContainerStatus { - containers := p.Spec.InitContainers - statuses := []v1.ContainerStatus{} - for _, container := range containers { - if status, found := statusMap[container.Name]; found { - statuses = append(statuses, *status) - } - } - return statuses -} - -// Reservation represents reserved resources for non-pod components. -type Reservation struct { - // System represents resources reserved for non-kubernetes components. - System v1.ResourceList - // Kubernetes represents resources reserved for kubernetes system components. - Kubernetes v1.ResourceList -} - -// ResolvedPodUID is a pod UID which has been translated/resolved to the representation known to kubelets. -type ResolvedPodUID types.UID - -// MirrorPodUID is a pod UID for a mirror pod. -type MirrorPodUID types.UID diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go deleted file mode 100644 index b6a1cc38c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_darwin.go +++ /dev/null @@ -1,45 +0,0 @@ -//go:build darwin -// +build darwin - -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "fmt" - "syscall" - "time" - "unsafe" - - "golang.org/x/sys/unix" -) - -// GetBootTime returns the time at which the machine was started, truncated to the nearest second -func GetBootTime() (time.Time, error) { - output, err := unix.SysctlRaw("kern.boottime") - if err != nil { - return time.Time{}, err - } - var timeval syscall.Timeval - if len(output) != int(unsafe.Sizeof(timeval)) { - return time.Time{}, fmt.Errorf("unexpected output when calling syscall kern.bootime. Expected len(output) to be %v, but got %v", - int(unsafe.Sizeof(timeval)), len(output)) - } - timeval = *(*syscall.Timeval)(unsafe.Pointer(&output[0])) - sec, nsec := timeval.Unix() - return time.Unix(sec, nsec).Truncate(time.Second), nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go deleted file mode 100644 index 7d605d761..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_freebsd.go +++ /dev/null @@ -1,40 +0,0 @@ -//go:build freebsd -// +build freebsd - -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "fmt" - "time" - - "golang.org/x/sys/unix" - "unsafe" -) - -// GetBootTime returns the time at which the machine was started, truncated to the nearest second -func GetBootTime() (time.Time, error) { - currentTime := time.Now() - ts := &unix.Timeval{} - _, _, e1 := unix.Syscall(uintptr(unix.SYS_CLOCK_GETTIME), uintptr(unix.CLOCK_UPTIME), uintptr(unsafe.Pointer(ts)), 0) - if e1 != 0 { - return time.Time{}, fmt.Errorf("error getting system uptime") - } - - return currentTime.Add(-time.Duration(ts.Sec) * time.Second).Truncate(time.Second), nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go deleted file mode 100644 index 935b3d803..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/boottime_util_linux.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build linux -// +build linux - -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "fmt" - "os" - "strconv" - "strings" - "time" - - "golang.org/x/sys/unix" - "k8s.io/klog/v2" -) - -// GetBootTime returns the time at which the machine was started, truncated to the nearest second. -// It uses /proc/stat first, which is more accurate, and falls back to the less accurate -// unix.Sysinfo if /proc/stat failed. -func GetBootTime() (time.Time, error) { - bootTime, err := getBootTimeWithProcStat() - if err != nil { - klog.InfoS("Failed to get boot time from /proc/uptime. Will retry with unix.Sysinfo.", "error", err) - return getBootTimeWithSysinfo() - } - return bootTime, nil -} - -func getBootTimeWithProcStat() (time.Time, error) { - raw, err := os.ReadFile("/proc/stat") - if err != nil { - return time.Time{}, fmt.Errorf("error getting boot time: %w", err) - } - rawFields := strings.Fields(string(raw)) - for i, v := range rawFields { - if v == "btime" { - if len(rawFields) > i+1 { - sec, err := strconv.ParseInt(rawFields[i+1], 10, 64) - if err != nil { - return time.Time{}, fmt.Errorf("error parsing boot time %s: %w", rawFields[i+1], err) - } - return time.Unix(sec, 0), nil - } - break - } - } - - return time.Time{}, fmt.Errorf("can not find btime from /proc/stat: %s", raw) -} - -func getBootTimeWithSysinfo() (time.Time, error) { - currentTime := time.Now() - var info unix.Sysinfo_t - if err := unix.Sysinfo(&info); err != nil { - return time.Time{}, fmt.Errorf("error getting system uptime: %w", err) - } - return currentTime.Add(-time.Duration(info.Uptime) * time.Second).Truncate(time.Second), nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/doc.go deleted file mode 100644 index 0f119d2f5..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package util holds utility functions. -package util diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go deleted file mode 100644 index 65fc8cf54..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/format/pod.go +++ /dev/null @@ -1,41 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package format - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" -) - -// Pod returns a string representing a pod in a consistent human readable format, -// with pod UID as part of the string. -func Pod(pod *v1.Pod) string { - if pod == nil { - return "" - } - return PodDesc(pod.Name, pod.Namespace, pod.UID) -} - -// PodDesc returns a string representing a pod in a consistent human readable format, -// with pod UID as part of the string. -func PodDesc(podName, podNamespace string, podUID types.UID) string { - // Use underscore as the delimiter because it is not allowed in pod name - // (DNS subdomain format), while allowed in the container name format. - return fmt.Sprintf("%s_%s(%s)", podName, podNamespace, podUID) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/node_startup_latency_tracker.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/node_startup_latency_tracker.go deleted file mode 100644 index 815e4e81e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/node_startup_latency_tracker.go +++ /dev/null @@ -1,103 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "sync" - "time" - - "k8s.io/kubernetes/pkg/kubelet/metrics" - "k8s.io/utils/clock" -) - -type NodeStartupLatencyTracker interface { - // This function may be called across Kubelet restart. - RecordAttemptRegisterNode() - // This function should not be called across Kubelet restart. - RecordRegisteredNewNode() - // This function may be called across Kubelet restart. - RecordNodeReady() -} - -type basicNodeStartupLatencyTracker struct { - lock sync.Mutex - - bootTime time.Time - kubeletStartTime time.Time - firstRegistrationAttemptTime time.Time - firstRegisteredNewNodeTime time.Time - firstNodeReadyTime time.Time - - // For testability - clock clock.Clock -} - -func NewNodeStartupLatencyTracker() NodeStartupLatencyTracker { - bootTime, err := GetBootTime() - if err != nil { - bootTime = time.Time{} - } - return &basicNodeStartupLatencyTracker{ - bootTime: bootTime, - kubeletStartTime: time.Now(), - clock: clock.RealClock{}, - } -} - -func (n *basicNodeStartupLatencyTracker) RecordAttemptRegisterNode() { - n.lock.Lock() - defer n.lock.Unlock() - - if !n.firstRegistrationAttemptTime.IsZero() { - return - } - - n.firstRegistrationAttemptTime = n.clock.Now() -} - -func (n *basicNodeStartupLatencyTracker) RecordRegisteredNewNode() { - n.lock.Lock() - defer n.lock.Unlock() - - if n.firstRegistrationAttemptTime.IsZero() || !n.firstRegisteredNewNodeTime.IsZero() { - return - } - - n.firstRegisteredNewNodeTime = n.clock.Now() - - if !n.bootTime.IsZero() { - metrics.NodeStartupPreKubeletDuration.Set(n.kubeletStartTime.Sub(n.bootTime).Seconds()) - } - metrics.NodeStartupPreRegistrationDuration.Set(n.firstRegistrationAttemptTime.Sub(n.kubeletStartTime).Seconds()) - metrics.NodeStartupRegistrationDuration.Set(n.firstRegisteredNewNodeTime.Sub(n.firstRegistrationAttemptTime).Seconds()) -} - -func (n *basicNodeStartupLatencyTracker) RecordNodeReady() { - n.lock.Lock() - defer n.lock.Unlock() - - if n.firstRegisteredNewNodeTime.IsZero() || !n.firstNodeReadyTime.IsZero() { - return - } - - n.firstNodeReadyTime = n.clock.Now() - - metrics.NodeStartupPostRegistrationDuration.Set(n.firstNodeReadyTime.Sub(n.firstRegisteredNewNodeTime).Seconds()) - if !n.bootTime.IsZero() { - metrics.NodeStartupDuration.Set(n.firstNodeReadyTime.Sub(n.bootTime).Seconds()) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/nodelease.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/nodelease.go deleted file mode 100644 index 9e1b00b76..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/nodelease.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "context" - - coordinationv1 "k8s.io/api/coordination/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - clientset "k8s.io/client-go/kubernetes" - - "k8s.io/klog/v2" -) - -// SetNodeOwnerFunc helps construct a newLeasePostProcessFunc which sets -// a node OwnerReference to the given lease object -func SetNodeOwnerFunc(c clientset.Interface, nodeName string) func(lease *coordinationv1.Lease) error { - return func(lease *coordinationv1.Lease) error { - // Setting owner reference needs node's UID. Note that it is different from - // kubelet.nodeRef.UID. When lease is initially created, it is possible that - // the connection between master and node is not ready yet. So try to set - // owner reference every time when renewing the lease, until successful. - if len(lease.OwnerReferences) == 0 { - if node, err := c.CoreV1().Nodes().Get(context.TODO(), nodeName, metav1.GetOptions{}); err == nil { - lease.OwnerReferences = []metav1.OwnerReference{ - { - APIVersion: corev1.SchemeGroupVersion.WithKind("Node").Version, - Kind: corev1.SchemeGroupVersion.WithKind("Node").Kind, - Name: nodeName, - UID: node.UID, - }, - } - } else { - klog.ErrorS(err, "Failed to get node when trying to set owner ref to the node lease", "node", klog.KRef("", nodeName)) - return err - } - } - return nil - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go deleted file mode 100644 index 3ab3d2aaa..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/pod_startup_latency_tracker.go +++ /dev/null @@ -1,196 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/kubelet/metrics" - "k8s.io/utils/clock" -) - -// PodStartupLatencyTracker records key moments for startup latency calculation, -// e.g. image pulling or pod observed running on watch. -type PodStartupLatencyTracker interface { - ObservedPodOnWatch(pod *v1.Pod, when time.Time) - RecordImageStartedPulling(podUID types.UID) - RecordImageFinishedPulling(podUID types.UID) - RecordStatusUpdated(pod *v1.Pod) - DeletePodStartupState(podUID types.UID) -} - -type basicPodStartupLatencyTracker struct { - // protect against concurrent read and write on pods map - lock sync.Mutex - pods map[types.UID]*perPodState - // metrics for the first network pod only - firstNetworkPodSeen bool - // For testability - clock clock.Clock -} - -type perPodState struct { - firstStartedPulling time.Time - lastFinishedPulling time.Time - // first time, when pod status changed into Running - observedRunningTime time.Time - // log, if pod latency was already Observed - metricRecorded bool -} - -// NewPodStartupLatencyTracker creates an instance of PodStartupLatencyTracker -func NewPodStartupLatencyTracker() PodStartupLatencyTracker { - return &basicPodStartupLatencyTracker{ - pods: map[types.UID]*perPodState{}, - clock: clock.RealClock{}, - } -} - -func (p *basicPodStartupLatencyTracker) ObservedPodOnWatch(pod *v1.Pod, when time.Time) { - p.lock.Lock() - defer p.lock.Unlock() - - // if the pod is terminal, we do not have to track it anymore for startup - if pod.Status.Phase == v1.PodFailed || pod.Status.Phase == v1.PodSucceeded { - delete(p.pods, pod.UID) - return - } - - state := p.pods[pod.UID] - if state == nil { - // create a new record for pod, only if it was not yet acknowledged by the Kubelet - // this is required, as we want to log metric only for those pods, that where scheduled - // after Kubelet started - if pod.Status.StartTime.IsZero() { - p.pods[pod.UID] = &perPodState{} - } - - return - } - - if state.observedRunningTime.IsZero() { - // skip, pod didn't start yet - return - } - - if state.metricRecorded { - // skip, pod's latency already recorded - return - } - - if hasPodStartedSLO(pod) { - podStartingDuration := when.Sub(pod.CreationTimestamp.Time) - imagePullingDuration := state.lastFinishedPulling.Sub(state.firstStartedPulling) - podStartSLOduration := (podStartingDuration - imagePullingDuration).Seconds() - - klog.InfoS("Observed pod startup duration", - "pod", klog.KObj(pod), - "podStartSLOduration", podStartSLOduration, - "podStartE2EDuration", podStartingDuration, - "podCreationTimestamp", pod.CreationTimestamp.Time, - "firstStartedPulling", state.firstStartedPulling, - "lastFinishedPulling", state.lastFinishedPulling, - "observedRunningTime", state.observedRunningTime, - "watchObservedRunningTime", when) - - metrics.PodStartSLIDuration.WithLabelValues().Observe(podStartSLOduration) - metrics.PodStartTotalDuration.WithLabelValues().Observe(podStartingDuration.Seconds()) - state.metricRecorded = true - // if is the first Pod with network track the start values - // these metrics will help to identify problems with the CNI plugin - if !pod.Spec.HostNetwork && !p.firstNetworkPodSeen { - metrics.FirstNetworkPodStartSLIDuration.Set(podStartSLOduration) - p.firstNetworkPodSeen = true - } - } -} - -func (p *basicPodStartupLatencyTracker) RecordImageStartedPulling(podUID types.UID) { - p.lock.Lock() - defer p.lock.Unlock() - - state := p.pods[podUID] - if state == nil { - return - } - - if state.firstStartedPulling.IsZero() { - state.firstStartedPulling = p.clock.Now() - } -} - -func (p *basicPodStartupLatencyTracker) RecordImageFinishedPulling(podUID types.UID) { - p.lock.Lock() - defer p.lock.Unlock() - - state := p.pods[podUID] - if state == nil { - return - } - - state.lastFinishedPulling = p.clock.Now() // Now is always grater than values from the past. -} - -func (p *basicPodStartupLatencyTracker) RecordStatusUpdated(pod *v1.Pod) { - p.lock.Lock() - defer p.lock.Unlock() - - state := p.pods[pod.UID] - if state == nil { - return - } - - if state.metricRecorded { - // skip, pod latency already recorded - return - } - - if !state.observedRunningTime.IsZero() { - // skip, pod already started - return - } - - if hasPodStartedSLO(pod) { - klog.V(3).InfoS("Mark when the pod was running for the first time", "pod", klog.KObj(pod), "rv", pod.ResourceVersion) - state.observedRunningTime = p.clock.Now() - } -} - -// hasPodStartedSLO, check if for given pod, each container has been started at least once -// -// This should reflect "Pod startup latency SLI" definition -// ref: https://github.com/kubernetes/community/blob/master/sig-scalability/slos/pod_startup_latency.md -func hasPodStartedSLO(pod *v1.Pod) bool { - for _, cs := range pod.Status.ContainerStatuses { - if cs.State.Running == nil || cs.State.Running.StartedAt.IsZero() { - return false - } - } - - return true -} - -func (p *basicPodStartupLatencyTracker) DeletePodStartupState(podUID types.UID) { - p.lock.Lock() - defer p.lock.Unlock() - - delete(p.pods, podUID) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/doc.go deleted file mode 100644 index 04f0129b2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package store hosts a Store interface and its implementations. -package store diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/filestore.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/filestore.go deleted file mode 100644 index 17c313602..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/filestore.go +++ /dev/null @@ -1,158 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package store - -import ( - "fmt" - "os" - "path/filepath" - "strings" - - utilfs "k8s.io/kubernetes/pkg/util/filesystem" -) - -const ( - // Name prefix for the temporary files. - tmpPrefix = "." -) - -// FileStore is an implementation of the Store interface which stores data in files. -type FileStore struct { - // Absolute path to the base directory for storing data files. - directoryPath string - - // filesystem to use. - filesystem utilfs.Filesystem -} - -// NewFileStore returns an instance of FileStore. -func NewFileStore(path string, fs utilfs.Filesystem) (Store, error) { - if err := fs.MkdirAll(path, 0755); err != nil { - return nil, err - } - return &FileStore{directoryPath: path, filesystem: fs}, nil -} - -// Write writes the given data to a file named key. -func (f *FileStore) Write(key string, data []byte) error { - if err := ValidateKey(key); err != nil { - return err - } - if err := f.filesystem.MkdirAll(f.directoryPath, 0755); err != nil { - return err - } - - return writeFile(f.filesystem, f.getPathByKey(key), data) -} - -// Read reads the data from the file named key. -func (f *FileStore) Read(key string) ([]byte, error) { - if err := ValidateKey(key); err != nil { - return nil, err - } - bytes, err := f.filesystem.ReadFile(f.getPathByKey(key)) - if os.IsNotExist(err) { - return bytes, ErrKeyNotFound - } - return bytes, err -} - -// Delete deletes the key file. -func (f *FileStore) Delete(key string) error { - if err := ValidateKey(key); err != nil { - return err - } - return removePath(f.filesystem, f.getPathByKey(key)) -} - -// List returns all keys in the store. -func (f *FileStore) List() ([]string, error) { - keys := make([]string, 0) - files, err := f.filesystem.ReadDir(f.directoryPath) - if err != nil { - return keys, err - } - for _, f := range files { - if !strings.HasPrefix(f.Name(), tmpPrefix) { - keys = append(keys, f.Name()) - } - } - return keys, nil -} - -// getPathByKey returns the full path of the file for the key. -func (f *FileStore) getPathByKey(key string) string { - return filepath.Join(f.directoryPath, key) -} - -// writeFile writes data to path in a single transaction. -func writeFile(fs utilfs.Filesystem, path string, data []byte) (retErr error) { - // Create a temporary file in the base directory of `path` with a prefix. - tmpFile, err := fs.TempFile(filepath.Dir(path), tmpPrefix) - if err != nil { - return err - } - - tmpPath := tmpFile.Name() - shouldClose := true - - defer func() { - // Close the file. - if shouldClose { - if err := tmpFile.Close(); err != nil { - if retErr == nil { - retErr = fmt.Errorf("close error: %v", err) - } else { - retErr = fmt.Errorf("failed to close temp file after error %v; close error: %v", retErr, err) - } - } - } - - // Clean up the temp file on error. - if retErr != nil && tmpPath != "" { - if err := removePath(fs, tmpPath); err != nil { - retErr = fmt.Errorf("failed to remove the temporary file (%q) after error %v; remove error: %v", tmpPath, retErr, err) - } - } - }() - - // Write data. - if _, err := tmpFile.Write(data); err != nil { - return err - } - - // Sync file. - if err := tmpFile.Sync(); err != nil { - return err - } - - // Closing the file before renaming. - err = tmpFile.Close() - shouldClose = false - if err != nil { - return err - } - - return fs.Rename(tmpPath, path) -} - -func removePath(fs utilfs.Filesystem, path string) error { - if err := fs.Remove(path); err != nil && !os.IsNotExist(err) { - return err - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/store.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/store.go deleted file mode 100644 index e797fd812..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/store/store.go +++ /dev/null @@ -1,64 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package store - -import ( - "fmt" - "regexp" -) - -const ( - keyMaxLength = 250 - - keyCharFmt string = "[A-Za-z0-9]" - keyExtCharFmt string = "[-A-Za-z0-9_.]" - qualifiedKeyFmt string = "(" + keyCharFmt + keyExtCharFmt + "*)?" + keyCharFmt -) - -var ( - // Key must consist of alphanumeric characters, '-', '_' or '.', and must start - // and end with an alphanumeric character. - keyRegex = regexp.MustCompile("^" + qualifiedKeyFmt + "$") - - // ErrKeyNotFound is the error returned if key is not found in Store. - ErrKeyNotFound = fmt.Errorf("key is not found") -) - -// Store provides the interface for storing keyed data. -// Store must be thread-safe -type Store interface { - // key must contain one or more characters in [A-Za-z0-9] - // Write writes data with key. - Write(key string, data []byte) error - // Read retrieves data with key - // Read must return ErrKeyNotFound if key is not found. - Read(key string) ([]byte, error) - // Delete deletes data by key - // Delete must not return error if key does not exist - Delete(key string) error - // List lists all existing keys. - List() ([]string, error) -} - -// ValidateKey returns an error if the given key does not meet the requirement -// of the key format and length. -func ValidateKey(key string) error { - if len(key) <= keyMaxLength && keyRegex.MatchString(key) { - return nil - } - return fmt.Errorf("invalid key: %q", key) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/swap/swap_util.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/swap/swap_util.go deleted file mode 100644 index 20f0e45ef..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/swap/swap_util.go +++ /dev/null @@ -1,149 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package swap - -import ( - "bytes" - "errors" - "os" - sysruntime "runtime" - "strings" - "sync" - - inuserns "github.com/moby/sys/userns" - "k8s.io/apimachinery/pkg/util/version" - "k8s.io/klog/v2" - utilkernel "k8s.io/kubernetes/pkg/util/kernel" - "k8s.io/mount-utils" -) - -var ( - tmpfsNoswapOptionSupported bool - tmpfsNoswapOptionAvailabilityOnce sync.Once - swapOn bool - swapOnErr error - swapOnOnce sync.Once -) - -const TmpfsNoswapOption = "noswap" - -func IsTmpfsNoswapOptionSupported(mounter mount.Interface, mountPath string) bool { - isTmpfsNoswapOptionSupportedHelper := func() bool { - if sysruntime.GOOS == "windows" { - return false - } - - if inuserns.RunningInUserNS() { - // Turning off swap in unprivileged tmpfs mounts unsupported - // https://github.com/torvalds/linux/blob/v6.8/mm/shmem.c#L4004-L4011 - // https://github.com/kubernetes/kubernetes/issues/125137 - klog.InfoS("Running under a user namespace - tmpfs noswap is not supported") - return false - } - - kernelVersion, err := utilkernel.GetVersion() - if err != nil { - klog.ErrorS(err, "cannot determine kernel version, unable to determine is tmpfs noswap is supported") - return false - } - - if kernelVersion.AtLeast(version.MustParseGeneric(utilkernel.TmpfsNoswapSupportKernelVersion)) { - return true - } - - if mountPath == "" { - klog.ErrorS(errors.New("mount path is empty, falling back to /tmp"), "") - } - - mountPath, err = os.MkdirTemp(mountPath, "tmpfs-noswap-test-") - if err != nil { - klog.InfoS("error creating dir to test if tmpfs noswap is enabled. Assuming not supported", "mount path", mountPath, "error", err) - return false - } - - defer func() { - err = os.RemoveAll(mountPath) - if err != nil { - klog.ErrorS(err, "error removing test tmpfs dir", "mount path", mountPath) - } - }() - - err = mounter.MountSensitiveWithoutSystemd("tmpfs", mountPath, "tmpfs", []string{TmpfsNoswapOption}, nil) - if err != nil { - klog.InfoS("error mounting tmpfs with the noswap option. Assuming not supported", "error", err) - return false - } - - err = mounter.Unmount(mountPath) - if err != nil { - klog.ErrorS(err, "error unmounting test tmpfs dir", "mount path", mountPath) - } - - return true - } - - tmpfsNoswapOptionAvailabilityOnce.Do(func() { - tmpfsNoswapOptionSupported = isTmpfsNoswapOptionSupportedHelper() - }) - - return tmpfsNoswapOptionSupported -} - -// gets /proc/swaps's content as an input, returns true if swap is enabled. -func isSwapOnAccordingToProcSwaps(procSwapsContent []byte) bool { - procSwapsContent = bytes.TrimSpace(procSwapsContent) // extra trailing \n - procSwapsStr := string(procSwapsContent) - procSwapsLines := strings.Split(procSwapsStr, "\n") - - // If there is more than one line (table headers) in /proc/swaps then swap is enabled - isSwapOn := len(procSwapsLines) > 1 - if isSwapOn { - klog.InfoS("Swap is on", "/proc/swaps contents", procSwapsStr) - } - - return isSwapOn -} - -// IsSwapOn detects whether swap in enabled on the system by inspecting -// /proc/swaps. If the file does not exist, an os.NotFound error will be returned. -// If running on windows, swap is assumed to always be false. -func IsSwapOn() (bool, error) { - isSwapOnHelper := func() (bool, error) { - if sysruntime.GOOS == "windows" { - return false, nil - } - - const swapFilePath = "/proc/swaps" - procSwapsContent, err := os.ReadFile(swapFilePath) - if err != nil { - if os.IsNotExist(err) { - klog.InfoS("File does not exist, assuming that swap is disabled", "path", swapFilePath) - return false, nil - } - - return false, err - } - - return isSwapOnAccordingToProcSwaps(procSwapsContent), nil - } - - swapOnOnce.Do(func() { - swapOn, swapOnErr = isSwapOnHelper() - }) - - return swapOn, swapOnErr -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go deleted file mode 100644 index 79473a181..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util.go +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/kubernetes/pkg/util/filesystem" -) - -// FromApiserverCache modifies so that the GET request will -// be served from apiserver cache instead of from etcd. -func FromApiserverCache(opts *metav1.GetOptions) { - opts.ResourceVersion = "0" -} - -var IsUnixDomainSocket = filesystem.IsUnixDomainSocket - -// GetNodenameForKernel gets hostname value to set in the hostname field (the nodename field of struct utsname) of the pod. -func GetNodenameForKernel(hostname string, hostDomainName string, setHostnameAsFQDN *bool) (string, error) { - kernelHostname := hostname - // FQDN has to be 64 chars to fit in the Linux nodename kernel field (specification 64 chars and the null terminating char). - const fqdnMaxLen = 64 - if len(hostDomainName) > 0 && setHostnameAsFQDN != nil && *setHostnameAsFQDN { - fqdn := fmt.Sprintf("%s.%s", hostname, hostDomainName) - // FQDN has to be shorter than hostnameMaxLen characters. - if len(fqdn) > fqdnMaxLen { - return "", fmt.Errorf("failed to construct FQDN from pod hostname and cluster domain, FQDN %s is too long (%d characters is the max, %d characters requested)", fqdn, fqdnMaxLen, len(fqdn)) - } - kernelHostname = fqdn - } - return kernelHostname, nil -} - -// GetContainerByIndex validates and extracts the container at index "idx" from -// "containers" with respect to "statuses". -// It returns true if the container is valid, else returns false. -func GetContainerByIndex(containers []v1.Container, statuses []v1.ContainerStatus, idx int) (v1.Container, bool) { - if idx < 0 || idx >= len(containers) || idx >= len(statuses) { - return v1.Container{}, false - } - if statuses[idx].Name != containers[idx].Name { - return v1.Container{}, false - } - return containers[idx], true -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go deleted file mode 100644 index 98efbb46f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_linux.go +++ /dev/null @@ -1,29 +0,0 @@ -//go:build linux -// +build linux - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - libcontainercgroups "github.com/opencontainers/cgroups" -) - -// IsCgroup2UnifiedMode returns true if the cgroup v2 unified mode is enabled -func IsCgroup2UnifiedMode() bool { - return libcontainercgroups.IsCgroup2UnifiedMode() -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go deleted file mode 100644 index e2e1c71ba..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_others.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build !linux && !windows -// +build !linux,!windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -// IsCgroup2UnifiedMode is a no-op for other OSes. -func IsCgroup2UnifiedMode() bool { - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go deleted file mode 100644 index 0664b6a42..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unix.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build freebsd || linux || darwin -// +build freebsd linux darwin - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "net/url" - "path/filepath" -) - -const ( - // unixProtocol is the network protocol of unix socket. - unixProtocol = "unix" -) - -// LocalEndpoint returns the full path to a unix socket at the given endpoint -func LocalEndpoint(path, file string) (string, error) { - u := url.URL{ - Scheme: unixProtocol, - Path: path, - } - return filepath.Join(u.String(), file+".sock"), nil -} - -// NormalizePath is a no-op for Linux for now -func NormalizePath(path string) string { - return path -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go deleted file mode 100644 index e95a7c583..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_unsupported.go +++ /dev/null @@ -1,44 +0,0 @@ -//go:build !freebsd && !linux && !windows && !darwin -// +build !freebsd,!linux,!windows,!darwin - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "fmt" - "time" -) - -// LockAndCheckSubPath empty implementation -func LockAndCheckSubPath(volumePath, subPath string) ([]uintptr, error) { - return []uintptr{}, nil -} - -// UnlockPath empty implementation -func UnlockPath(fileHandles []uintptr) { -} - -// LocalEndpoint empty implementation -func LocalEndpoint(path, file string) (string, error) { - return "", fmt.Errorf("LocalEndpoints are unsupported in this build") -} - -// GetBootTime empty implementation -func GetBootTime() (time.Time, error) { - return time.Time{}, fmt.Errorf("GetBootTime is unsupported in this build") -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go deleted file mode 100644 index c944a7d22..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/util/util_windows.go +++ /dev/null @@ -1,80 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "fmt" - "path/filepath" - "strings" - "syscall" - "time" -) - -const npipeProtocol = "npipe" - -// LocalEndpoint returns the full path to a named pipe at the given endpoint - unlike on unix, we can't use sockets. -func LocalEndpoint(path, file string) (string, error) { - // extract the podresources config name from the path. We only need this on windows because the preferred layout of pipes, - // this is why we have the extra logic in here instead of changing the function signature. Join the file to make sure the - // last path component is a file, so the operation chain works.. - podResourcesDir := filepath.Base(filepath.Dir(filepath.Join(path, file))) - if podResourcesDir == "" { - // should not happen because the user can configure a root directory, and we expected a subdirectory inside - // the user supplied root directory named like "pod-resources" or so. - return "", fmt.Errorf("cannot infer the podresources directory from path %q", path) - } - // windows pipes are expected to use forward slashes: https://learn.microsoft.com/windows/win32/ipc/pipe-names - // so using `url` like we do on unix gives us unclear benefits - see https://github.com/kubernetes/kubernetes/issues/78628 - // So we just construct the path from scratch. - // Format: \\ServerName\pipe\PipeName - // Where where ServerName is either the name of a remote computer or a period, to specify the local computer. - // We only consider PipeName as regular windows path, while the pipe path components are fixed, hence we use constants. - serverPart := `\\.` - pipePart := "pipe" - pipeName := "kubelet-" + podResourcesDir - return npipeProtocol + "://" + filepath.Join(serverPart, pipePart, pipeName), nil -} - -var tickCount = syscall.NewLazyDLL("kernel32.dll").NewProc("GetTickCount64") - -// GetBootTime returns the time at which the machine was started, truncated to the nearest second -func GetBootTime() (time.Time, error) { - currentTime := time.Now() - output, _, err := tickCount.Call() - if errno, ok := err.(syscall.Errno); !ok || errno != 0 { - return time.Time{}, err - } - return currentTime.Add(-time.Duration(output) * time.Millisecond).Truncate(time.Second), nil -} - -// NormalizePath converts FS paths returned by certain go frameworks (like fsnotify) -// to native Windows paths that can be passed to Windows specific code -func NormalizePath(path string) string { - path = strings.ReplaceAll(path, "/", "\\") - if strings.HasPrefix(path, "\\") { - path = "c:" + path - } - return path -} - -// IsCgroup2UnifiedMode is a no-op for Windows for now -func IsCgroup2UnifiedMode() bool { - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go deleted file mode 100644 index c6a7eab5c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/cpu_topology.go +++ /dev/null @@ -1,264 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package winstats - -import ( - "fmt" - "syscall" - "unsafe" - - cadvisorapi "github.com/google/cadvisor/info/v1" - "k8s.io/klog/v2" -) - -var ( - procGetLogicalProcessorInformationEx = modkernel32.NewProc("GetLogicalProcessorInformationEx") - getNumaAvailableMemoryNodeEx = modkernel32.NewProc("GetNumaAvailableMemoryNodeEx") - procGetNumaNodeProcessorMaskEx = modkernel32.NewProc("GetNumaNodeProcessorMaskEx") -) - -type relationType int - -const ( - relationProcessorCore relationType = iota - relationNumaNode - relationCache - relationProcessorPackage - relationGroup - relationProcessorDie - relationNumaNodeEx - relationProcessorModule - relationAll = 0xffff -) - -type systemLogicalProcessorInformationEx struct { - Relationship uint32 - Size uint32 - data interface{} -} - -type processorRelationship struct { - Flags byte - EfficiencyClass byte - Reserved [20]byte - GroupCount uint16 - // groupMasks is an []GroupAffinity. In c++ this is a union of either one or many GroupAffinity based on GroupCount - GroupMasks interface{} -} - -// GroupAffinity represents the processor group affinity of cpus -// https://learn.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-group_affinity -type GroupAffinity struct { - Mask uint64 - Group uint16 - Reserved [3]uint16 -} - -// MaskString returns the affinity mask as a string of 0s and 1s -func (a GroupAffinity) MaskString() string { - return fmt.Sprintf("%064b", a.Mask) -} - -// Processors returns a list of processors ids that are part of the affinity mask -// Windows doesn't track processors by ID but kubelet converts them to a number -func (a GroupAffinity) Processors() []int { - processors := []int{} - for i := 0; i < 64; i++ { - if a.Mask&(1< len(buffer) { - return 0, 0, nil, fmt.Errorf("remaining buffer too small while reading windows processor relationship") - } - info := (*systemLogicalProcessorInformationEx)(unsafe.Pointer(&buffer[offset])) - // check one more time now that we know the size of the struct - if offset+int(info.Size) > len(buffer) { - return 0, 0, nil, fmt.Errorf("remaining buffer too small while reading windows processor relationship") - } - switch (relationType)(info.Relationship) { - case relationProcessorCore, relationProcessorPackage: - relationship := (*processorRelationship)(unsafe.Pointer(&info.data)) - groupMasks := make([]GroupAffinity, relationship.GroupCount) - for i := 0; i < int(relationship.GroupCount); i++ { - groupMasks[i] = *(*GroupAffinity)(unsafe.Pointer(uintptr(unsafe.Pointer(&relationship.GroupMasks)) + uintptr(i)*unsafe.Sizeof(GroupAffinity{}))) - } - - if relationProcessorCore == (relationType)(info.Relationship) { - numOfcores++ - } - - if relationProcessorPackage == (relationType)(info.Relationship) { - numofSockets++ - } - - //iterate over group masks and add each processor to the map - for _, groupMask := range groupMasks { - for _, processorId := range groupMask.Processors() { - p, ok := logicalProcessors[processorId] - if !ok { - p = &processor{} - logicalProcessors[processorId] = p - } - if relationProcessorCore == (relationType)(info.Relationship) { - p.CoreID = numOfcores - } - if relationProcessorPackage == (relationType)(info.Relationship) { - p.SocketID = numofSockets - } - } - } - - case relationNumaNode, relationNumaNodeEx: - numaNodeRelationship := (*numaNodeRelationship)(unsafe.Pointer(&info.data)) - groupMasks := make([]GroupAffinity, numaNodeRelationship.GroupCount) - for i := 0; i < int(numaNodeRelationship.GroupCount); i++ { - groupMasks[i] = *(*GroupAffinity)(unsafe.Pointer(uintptr(unsafe.Pointer(&numaNodeRelationship.GroupMasks)) + uintptr(i)*unsafe.Sizeof(GroupAffinity{}))) - } - - nodes = append(nodes, cadvisorapi.Node{Id: int(numaNodeRelationship.NodeNumber)}) - - for _, groupMask := range groupMasks { - for processorId := range groupMask.Processors() { - p, ok := logicalProcessors[processorId] - if !ok { - p = &processor{} - logicalProcessors[processorId] = p - } - p.NodeID = int(numaNodeRelationship.NodeNumber) - } - } - - default: - klog.V(4).Infof("Not using Windows CPU relationship type: %d", info.Relationship) - } - - // Move the offset to the next SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX struct - offset += int(info.Size) - } - - for processId, p := range logicalProcessors { - node := nodes[p.NodeID] - if node.Id != p.NodeID { - return 0, 0, nil, fmt.Errorf("node ID mismatch: %d != %d", node.Id, p.NodeID) - } - availableBytes := uint64(0) - r1, _, err := getNumaAvailableMemoryNodeEx.Call(uintptr(p.NodeID), uintptr(unsafe.Pointer(&availableBytes))) - if r1 == 0 { - return 0, 0, nil, fmt.Errorf("call to GetNumaAvailableMemoryNodeEx failed: %v", err) - } - node.Memory = availableBytes - node.AddThread(processId, p.CoreID) - ok, coreIdx := node.FindCore(p.CoreID) - if !ok { - return 0, 0, nil, fmt.Errorf("core not found: %d", p.CoreID) - } - node.Cores[coreIdx].SocketID = p.SocketID - nodes[p.NodeID] = node - } - - return numOfcores, numofSockets, nodes, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/doc.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/doc.go deleted file mode 100644 index 9802d587b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package winstats provides a client to get node and pod level stats on windows -package winstats diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go deleted file mode 100644 index eb7f4cd8c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/network_stats.go +++ /dev/null @@ -1,313 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package winstats - -import ( - "sync" - - cadvisorapi "github.com/google/cadvisor/info/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/klog/v2" -) - -const ( - packetsReceivedPerSecondQuery = "\\Network Adapter(*)\\Packets Received/sec" - packetsSentPerSecondQuery = "\\Network Adapter(*)\\Packets Sent/sec" - bytesReceivedPerSecondQuery = "\\Network Adapter(*)\\Bytes Received/sec" - bytesSentPerSecondQuery = "\\Network Adapter(*)\\Bytes Sent/sec" - packetsReceivedDiscardedQuery = "\\Network Adapter(*)\\Packets Received Discarded" - packetsReceivedErrorsQuery = "\\Network Adapter(*)\\Packets Received Errors" - packetsOutboundDiscardedQuery = "\\Network Adapter(*)\\Packets Outbound Discarded" - packetsOutboundErrorsQuery = "\\Network Adapter(*)\\Packets Outbound Errors" -) - -// networkCounter contains the counters for network adapters. -type networkCounter struct { - packetsReceivedPerSecondCounter perfCounter - packetsSentPerSecondCounter perfCounter - bytesReceivedPerSecondCounter perfCounter - bytesSentPerSecondCounter perfCounter - packetsReceivedDiscardedCounter perfCounter - packetsReceivedErrorsCounter perfCounter - packetsOutboundDiscardedCounter perfCounter - packetsOutboundErrorsCounter perfCounter - - mu sync.RWMutex - adapterStats map[string]cadvisorapi.InterfaceStats -} - -func newNetworkCounters() (*networkCounter, error) { - packetsReceivedPerSecondCounter, err := newPerfCounter(packetsReceivedPerSecondQuery) - if err != nil { - return nil, err - } - - packetsSentPerSecondCounter, err := newPerfCounter(packetsSentPerSecondQuery) - if err != nil { - return nil, err - } - - bytesReceivedPerSecondCounter, err := newPerfCounter(bytesReceivedPerSecondQuery) - if err != nil { - return nil, err - } - - bytesSentPerSecondCounter, err := newPerfCounter(bytesSentPerSecondQuery) - if err != nil { - return nil, err - } - - packetsReceivedDiscardedCounter, err := newPerfCounter(packetsReceivedDiscardedQuery) - if err != nil { - return nil, err - } - - packetsReceivedErrorsCounter, err := newPerfCounter(packetsReceivedErrorsQuery) - if err != nil { - return nil, err - } - - packetsOutboundDiscardedCounter, err := newPerfCounter(packetsOutboundDiscardedQuery) - if err != nil { - return nil, err - } - - packetsOutboundErrorsCounter, err := newPerfCounter(packetsOutboundErrorsQuery) - if err != nil { - return nil, err - } - - return &networkCounter{ - packetsReceivedPerSecondCounter: packetsReceivedPerSecondCounter, - packetsSentPerSecondCounter: packetsSentPerSecondCounter, - bytesReceivedPerSecondCounter: bytesReceivedPerSecondCounter, - bytesSentPerSecondCounter: bytesSentPerSecondCounter, - packetsReceivedDiscardedCounter: packetsReceivedDiscardedCounter, - packetsReceivedErrorsCounter: packetsReceivedErrorsCounter, - packetsOutboundDiscardedCounter: packetsOutboundDiscardedCounter, - packetsOutboundErrorsCounter: packetsOutboundErrorsCounter, - adapterStats: map[string]cadvisorapi.InterfaceStats{}, - }, nil -} - -func (n *networkCounter) getData() ([]cadvisorapi.InterfaceStats, error) { - packetsReceivedPerSecondData, err := n.packetsReceivedPerSecondCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get packetsReceivedPerSecond perf counter data") - return nil, err - } - - packetsSentPerSecondData, err := n.packetsSentPerSecondCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get packetsSentPerSecond perf counter data") - return nil, err - } - - bytesReceivedPerSecondData, err := n.bytesReceivedPerSecondCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get bytesReceivedPerSecond perf counter data") - return nil, err - } - - bytesSentPerSecondData, err := n.bytesSentPerSecondCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get bytesSentPerSecond perf counter data") - return nil, err - } - - packetsReceivedDiscardedData, err := n.packetsReceivedDiscardedCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get packetsReceivedDiscarded perf counter data") - return nil, err - } - - packetsReceivedErrorsData, err := n.packetsReceivedErrorsCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get packetsReceivedErrors perf counter data") - return nil, err - } - - packetsOutboundDiscardedData, err := n.packetsOutboundDiscardedCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get packetsOutboundDiscarded perf counter data") - return nil, err - } - - packetsOutboundErrorsData, err := n.packetsOutboundErrorsCounter.getDataList() - if err != nil { - klog.ErrorS(err, "Unable to get packetsOutboundErrors perf counter data") - return nil, err - } - - n.mu.Lock() - defer n.mu.Unlock() - n.mergeCollectedData( - packetsReceivedPerSecondData, - packetsSentPerSecondData, - bytesReceivedPerSecondData, - bytesSentPerSecondData, - packetsReceivedDiscardedData, - packetsReceivedErrorsData, - packetsOutboundDiscardedData, - packetsOutboundErrorsData, - ) - return n.listInterfaceStats(), nil -} - -// mergeCollectedData merges the collected data into cache. It should be invoked under lock protected. -func (n *networkCounter) mergeCollectedData(packetsReceivedPerSecondData, - packetsSentPerSecondData, - bytesReceivedPerSecondData, - bytesSentPerSecondData, - packetsReceivedDiscardedData, - packetsReceivedErrorsData, - packetsOutboundDiscardedData, - packetsOutboundErrorsData map[string]uint64) { - adapters := sets.New[string]() - - // merge the collected data and list of adapters. - adapters.Insert(n.mergePacketsReceivedPerSecondData(packetsReceivedPerSecondData)...) - adapters.Insert(n.mergePacketsSentPerSecondData(packetsSentPerSecondData)...) - adapters.Insert(n.mergeBytesReceivedPerSecondData(bytesReceivedPerSecondData)...) - adapters.Insert(n.mergeBytesSentPerSecondData(bytesSentPerSecondData)...) - adapters.Insert(n.mergePacketsReceivedDiscardedData(packetsReceivedDiscardedData)...) - adapters.Insert(n.mergePacketsReceivedErrorsData(packetsReceivedErrorsData)...) - adapters.Insert(n.mergePacketsOutboundDiscardedData(packetsOutboundDiscardedData)...) - adapters.Insert(n.mergePacketsOutboundErrorsData(packetsOutboundErrorsData)...) - - // delete the cache for non-existing adapters. - for adapter := range n.adapterStats { - if !adapters.Has(adapter) { - delete(n.adapterStats, adapter) - } - } -} - -func (n *networkCounter) mergePacketsReceivedPerSecondData(packetsReceivedPerSecondData map[string]uint64) []string { - var adapters []string - for adapterName, value := range packetsReceivedPerSecondData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.RxPackets = newStat.RxPackets + value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) mergePacketsSentPerSecondData(packetsSentPerSecondData map[string]uint64) []string { - var adapters []string - for adapterName, value := range packetsSentPerSecondData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.TxPackets = newStat.TxPackets + value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) mergeBytesReceivedPerSecondData(bytesReceivedPerSecondData map[string]uint64) []string { - var adapters []string - for adapterName, value := range bytesReceivedPerSecondData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.RxBytes = newStat.RxBytes + value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) mergeBytesSentPerSecondData(bytesSentPerSecondData map[string]uint64) []string { - var adapters []string - for adapterName, value := range bytesSentPerSecondData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.TxBytes = newStat.TxBytes + value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) mergePacketsReceivedDiscardedData(packetsReceivedDiscardedData map[string]uint64) []string { - var adapters []string - for adapterName, value := range packetsReceivedDiscardedData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.RxDropped = value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) mergePacketsReceivedErrorsData(packetsReceivedErrorsData map[string]uint64) []string { - var adapters []string - for adapterName, value := range packetsReceivedErrorsData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.RxErrors = value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) mergePacketsOutboundDiscardedData(packetsOutboundDiscardedData map[string]uint64) []string { - var adapters []string - for adapterName, value := range packetsOutboundDiscardedData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.TxDropped = value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) mergePacketsOutboundErrorsData(packetsOutboundErrorsData map[string]uint64) []string { - var adapters []string - for adapterName, value := range packetsOutboundErrorsData { - adapters = append(adapters, adapterName) - newStat := n.adapterStats[adapterName] - newStat.Name = adapterName - newStat.TxErrors = value - n.adapterStats[adapterName] = newStat - } - - return adapters -} - -func (n *networkCounter) listInterfaceStats() []cadvisorapi.InterfaceStats { - stats := make([]cadvisorapi.InterfaceStats, 0, len(n.adapterStats)) - for _, stat := range n.adapterStats { - stats = append(stats, stat) - } - return stats -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go deleted file mode 100644 index df5fb41ef..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounter_nodestats_windows.go +++ /dev/null @@ -1,358 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package winstats - -import ( - "os" - "runtime" - "strconv" - "strings" - "sync" - "syscall" - "time" - "unsafe" - - utilfeature "k8s.io/apiserver/pkg/util/feature" - kubefeatures "k8s.io/kubernetes/pkg/features" - - cadvisorapi "github.com/google/cadvisor/info/v1" - "github.com/pkg/errors" - "golang.org/x/sys/windows" - "golang.org/x/sys/windows/registry" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/klog/v2" -) - -const ( - bootIdRegistry = `SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters` - bootIdKey = `BootId` -) - -// MemoryStatusEx is the same as Windows structure MEMORYSTATUSEX -// https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770(v=vs.85).aspx -type MemoryStatusEx struct { - Length uint32 - MemoryLoad uint32 - TotalPhys uint64 - AvailPhys uint64 - TotalPageFile uint64 - AvailPageFile uint64 - TotalVirtual uint64 - AvailVirtual uint64 - AvailExtendedVirtual uint64 -} - -// PerformanceInfo is the same as Windows structure PERFORMANCE_INFORMATION -// https://learn.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-performance_information -type PerformanceInformation struct { - cb uint32 - CommitTotalPages uint64 - CommitLimitPages uint64 - CommitPeakPages uint64 - PhysicalTotalPages uint64 - PhysicalAvailablePages uint64 - SystemCachePages uint64 - KernelTotalPages uint64 - KernelPagesPages uint64 - KernelNonpagedPages uint64 - PageSize uint64 - HandleCount uint32 - ProcessCount uint32 - ThreadCount uint32 -} - -var ( - // kernel32.dll system calls - modkernel32 = windows.NewLazySystemDLL("kernel32.dll") - procGlobalMemoryStatusEx = modkernel32.NewProc("GlobalMemoryStatusEx") - procGetActiveProcessorCount = modkernel32.NewProc("GetActiveProcessorCount") - // psapi.dll system calls - modpsapi = windows.NewLazySystemDLL("psapi.dll") - procGetPerformanceInfo = modpsapi.NewProc("GetPerformanceInfo") -) - -const allProcessorGroups = 0xFFFF - -// NewPerfCounterClient creates a client using perf counters -func NewPerfCounterClient() (Client, error) { - // Initialize the cache - initCache := cpuUsageCoreNanoSecondsCache{0, 0} - return newClient(&perfCounterNodeStatsClient{ - cpuUsageCoreNanoSecondsCache: initCache, - }) -} - -// perfCounterNodeStatsClient is a client that provides Windows Stats via PerfCounters -type perfCounterNodeStatsClient struct { - nodeMetrics - mu sync.RWMutex // mu protects nodeMetrics - nodeInfo - // cpuUsageCoreNanoSecondsCache caches the cpu usage for nodes. - cpuUsageCoreNanoSecondsCache -} - -func (p *perfCounterNodeStatsClient) startMonitoring() error { - memory, err := getPhysicallyInstalledSystemMemoryBytes() - if err != nil { - return err - } - - osInfo, err := GetOSInfo() - if err != nil { - return err - } - - p.nodeInfo = nodeInfo{ - kernelVersion: osInfo.GetPatchVersion(), - osImageVersion: osInfo.ProductName, - memoryPhysicalCapacityBytes: memory, - startTime: time.Now(), - } - - cpuCounter, err := newPerfCounter(cpuQuery) - if err != nil { - return err - } - - memWorkingSetCounter, err := newPerfCounter(memoryPrivWorkingSetQuery) - if err != nil { - return err - } - - memCommittedBytesCounter, err := newPerfCounter(memoryCommittedBytesQuery) - if err != nil { - return err - } - - networkAdapterCounter, err := newNetworkCounters() - if err != nil { - return err - } - - go wait.Forever(func() { - p.collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter, networkAdapterCounter) - }, perfCounterUpdatePeriod) - - // Cache the CPU usage every defaultCachePeriod - go wait.Forever(func() { - newValue := p.nodeMetrics.cpuUsageCoreNanoSeconds - p.mu.Lock() - defer p.mu.Unlock() - p.cpuUsageCoreNanoSecondsCache = cpuUsageCoreNanoSecondsCache{ - previousValue: p.cpuUsageCoreNanoSecondsCache.latestValue, - latestValue: newValue, - } - }, defaultCachePeriod) - - return nil -} - -func (p *perfCounterNodeStatsClient) getMachineInfo() (*cadvisorapi.MachineInfo, error) { - hostname, err := os.Hostname() - if err != nil { - return nil, err - } - - systemUUID, err := getSystemUUID() - if err != nil { - return nil, err - } - - bootId, err := getBootID() - if err != nil { - return nil, err - } - - mi := &cadvisorapi.MachineInfo{ - NumCores: ProcessorCount(), - MemoryCapacity: p.nodeInfo.memoryPhysicalCapacityBytes, - MachineID: hostname, - SystemUUID: systemUUID, - BootID: bootId, - } - - if utilfeature.DefaultFeatureGate.Enabled(kubefeatures.WindowsCPUAndMemoryAffinity) { - numOfPysicalCores, numOfSockets, topology, err := processorInfo(relationAll) - if err != nil { - return nil, err - } - - mi.NumPhysicalCores = numOfPysicalCores - mi.NumSockets = numOfSockets - mi.Topology = topology - } - - return mi, nil -} - -// ProcessorCount returns the number of logical processors on the system. -// runtime.NumCPU() will only return the information for a single Processor Group. -// Since a single group can only hold 64 logical processors, this -// means when there are more they will be divided into multiple groups. -// For the above reason, procGetActiveProcessorCount is used to get the -// cpu count for all processor groups of the windows node. -// more notes for this issue: -// same issue in moby: https://github.com/moby/moby/issues/38935#issuecomment-744638345 -// solution in hcsshim: https://github.com/microsoft/hcsshim/blob/master/internal/processorinfo/processor_count.go -func ProcessorCount() int { - if amount := getActiveProcessorCount(allProcessorGroups); amount != 0 { - return int(amount) - } - return runtime.NumCPU() -} - -func getActiveProcessorCount(groupNumber uint16) int { - r0, _, _ := syscall.Syscall(procGetActiveProcessorCount.Addr(), 1, uintptr(groupNumber), 0, 0) - return int(r0) -} - -func (p *perfCounterNodeStatsClient) getVersionInfo() (*cadvisorapi.VersionInfo, error) { - return &cadvisorapi.VersionInfo{ - KernelVersion: p.nodeInfo.kernelVersion, - ContainerOsVersion: p.nodeInfo.osImageVersion, - }, nil -} - -func (p *perfCounterNodeStatsClient) getNodeMetrics() (nodeMetrics, error) { - p.mu.RLock() - defer p.mu.RUnlock() - return p.nodeMetrics, nil -} - -func (p *perfCounterNodeStatsClient) getNodeInfo() nodeInfo { - return p.nodeInfo -} - -func (p *perfCounterNodeStatsClient) collectMetricsData(cpuCounter, memWorkingSetCounter, memCommittedBytesCounter perfCounter, networkAdapterCounter *networkCounter) { - cpuValue, err := cpuCounter.getData() - cpuCores := ProcessorCount() - if err != nil { - klog.ErrorS(err, "Unable to get cpu perf counter data") - return - } - - memWorkingSetValue, err := memWorkingSetCounter.getData() - if err != nil { - klog.ErrorS(err, "Unable to get memWorkingSet perf counter data") - return - } - - memCommittedBytesValue, err := memCommittedBytesCounter.getData() - if err != nil { - klog.ErrorS(err, "Unable to get memCommittedBytes perf counter data") - return - } - - networkAdapterStats, err := networkAdapterCounter.getData() - if err != nil { - klog.ErrorS(err, "Unable to get network adapter perf counter data") - return - } - - p.mu.Lock() - defer p.mu.Unlock() - p.nodeMetrics = nodeMetrics{ - cpuUsageCoreNanoSeconds: p.convertCPUValue(cpuCores, cpuValue), - cpuUsageNanoCores: p.getCPUUsageNanoCores(), - memoryPrivWorkingSetBytes: memWorkingSetValue, - memoryCommittedBytes: memCommittedBytesValue, - interfaceStats: networkAdapterStats, - timeStamp: time.Now(), - } -} - -func (p *perfCounterNodeStatsClient) convertCPUValue(cpuCores int, cpuValue uint64) uint64 { - // This converts perf counter data which is cpu percentage for all cores into nanoseconds. - // The formula is (cpuPercentage / 100.0) * #cores * 1e+9 (nano seconds). More info here: - // https://github.com/kubernetes/heapster/issues/650 - newValue := p.nodeMetrics.cpuUsageCoreNanoSeconds + uint64((float64(cpuValue)/100.0)*float64(cpuCores)*1e9) - return newValue -} - -func (p *perfCounterNodeStatsClient) getCPUUsageNanoCores() uint64 { - cachePeriodSeconds := uint64(defaultCachePeriod / time.Second) - perfCounterUpdatePeriodSeconds := uint64(perfCounterUpdatePeriod / time.Second) - cpuUsageNanoCores := ((p.cpuUsageCoreNanoSecondsCache.latestValue - p.cpuUsageCoreNanoSecondsCache.previousValue) * perfCounterUpdatePeriodSeconds) / cachePeriodSeconds - return cpuUsageNanoCores -} - -func getSystemUUID() (string, error) { - k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SYSTEM\HardwareConfig`, registry.QUERY_VALUE) - if err != nil { - return "", errors.Wrap(err, "failed to open registry key HKLM\\SYSTEM\\HardwareConfig") - } - defer k.Close() - - uuid, _, err := k.GetStringValue("LastConfig") - if err != nil { - return "", errors.Wrap(err, "failed to read registry value LastConfig from key HKLM\\SYSTEM\\HardwareConfig") - } - - uuid = strings.Trim(uuid, "{") - uuid = strings.Trim(uuid, "}") - uuid = strings.ToUpper(uuid) - return uuid, nil -} - -func getPhysicallyInstalledSystemMemoryBytes() (uint64, error) { - // We use GlobalMemoryStatusEx instead of GetPhysicallyInstalledSystemMemory - // on Windows node for the following reasons: - // 1. GetPhysicallyInstalledSystemMemory retrieves the amount of physically - // installed RAM from the computer's SMBIOS firmware tables. - // https://msdn.microsoft.com/en-us/library/windows/desktop/cc300158(v=vs.85).aspx - // On some VM, it is unable to read data from SMBIOS and fails with ERROR_INVALID_DATA. - // 2. On Linux node, total physical memory is read from MemTotal in /proc/meminfo. - // GlobalMemoryStatusEx returns the amount of physical memory that is available - // for the operating system to use. The amount returned by GlobalMemoryStatusEx - // is closer in parity with Linux - // https://www.kernel.org/doc/Documentation/filesystems/proc.txt - var statex MemoryStatusEx - statex.Length = uint32(unsafe.Sizeof(statex)) - ret, _, _ := procGlobalMemoryStatusEx.Call(uintptr(unsafe.Pointer(&statex))) - - if ret == 0 { - return 0, errors.New("unable to read physical memory") - } - - return statex.TotalPhys, nil -} - -func GetPerformanceInfo() (*PerformanceInformation, error) { - var pi PerformanceInformation - pi.cb = uint32(unsafe.Sizeof(pi)) - ret, _, _ := procGetPerformanceInfo.Call(uintptr(unsafe.Pointer(&pi)), uintptr(pi.cb)) - if ret == 0 { - return nil, errors.New("unable to read Windows performance information") - } - return &pi, nil -} - -func getBootID() (string, error) { - regKey, err := registry.OpenKey(registry.LOCAL_MACHINE, bootIdRegistry, registry.READ) - if err != nil { - return "", err - } - defer regKey.Close() - regValue, _, err := regKey.GetIntegerValue(bootIdKey) - if err != nil { - return "", err - } - return strconv.FormatUint(regValue, 10), nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go deleted file mode 100644 index 4b483d41d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/perfcounters.go +++ /dev/null @@ -1,136 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package winstats - -import ( - "errors" - "fmt" - "time" - "unsafe" - - "github.com/JeffAshton/win_pdh" -) - -const ( - cpuQuery = "\\Processor(_Total)\\% Processor Time" - memoryPrivWorkingSetQuery = "\\Process(_Total)\\Working Set - Private" - memoryCommittedBytesQuery = "\\Memory\\Committed Bytes" - // Perf counters are updated 10 seconds. This is the same as the default cadvisor housekeeping interval - // set at https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/cadvisor/cadvisor_linux.go - perfCounterUpdatePeriod = 10 * time.Second - // defaultCachePeriod is the default cache period for each cpuUsage. - // This matches with the cadvisor setting and the time interval we use for containers. - // see https://github.com/kubernetes/kubernetes/blob/master/pkg/kubelet/cadvisor/cadvisor_linux.go#L63 - defaultCachePeriod = 10 * time.Second -) - -type perfCounter interface { - getData() (uint64, error) - getDataList() (map[string]uint64, error) -} - -type perfCounterImpl struct { - queryHandle win_pdh.PDH_HQUERY - counterHandle win_pdh.PDH_HCOUNTER -} - -func newPerfCounter(counter string) (perfCounter, error) { - var queryHandle win_pdh.PDH_HQUERY - var counterHandle win_pdh.PDH_HCOUNTER - - ret := win_pdh.PdhOpenQuery(0, 0, &queryHandle) - if ret != win_pdh.ERROR_SUCCESS { - return nil, errors.New("unable to open query through DLL call") - } - - ret = win_pdh.PdhAddEnglishCounter(queryHandle, counter, 0, &counterHandle) - if ret != win_pdh.ERROR_SUCCESS { - return nil, fmt.Errorf("unable to add process counter: %s. Error code is %x", counter, ret) - } - - ret = win_pdh.PdhCollectQueryData(queryHandle) - if ret != win_pdh.ERROR_SUCCESS { - return nil, fmt.Errorf("unable to collect data from counter. Error code is %x", ret) - } - - return &perfCounterImpl{ - queryHandle: queryHandle, - counterHandle: counterHandle, - }, nil -} - -// getData is used for getting data without * in counter name. -func (p *perfCounterImpl) getData() (uint64, error) { - filledBuf, bufCount, err := p.getQueriedData() - if err != nil { - return 0, err - } - - var data uint64 = 0 - for i := 0; i < int(bufCount); i++ { - c := filledBuf[i] - data = uint64(c.FmtValue.DoubleValue) - } - - return data, nil -} - -// getDataList is used for getting data with * in counter name. -func (p *perfCounterImpl) getDataList() (map[string]uint64, error) { - filledBuf, bufCount, err := p.getQueriedData() - if err != nil { - return nil, err - } - - data := map[string]uint64{} - for i := 0; i < int(bufCount); i++ { - c := filledBuf[i] - value := uint64(c.FmtValue.DoubleValue) - name := win_pdh.UTF16PtrToString(c.SzName) - data[name] = value - } - - return data, nil -} - -// getQueriedData is used for getting data using the given query handle. -func (p *perfCounterImpl) getQueriedData() ([]win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, uint32, error) { - ret := win_pdh.PdhCollectQueryData(p.queryHandle) - if ret != win_pdh.ERROR_SUCCESS { - return nil, 0, fmt.Errorf("unable to collect data from counter. Error code is %x", ret) - } - - var bufSize, bufCount uint32 - var size = uint32(unsafe.Sizeof(win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE{})) - var emptyBuf [1]win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE // need at least 1 addressable null ptr. - - ret = win_pdh.PdhGetFormattedCounterArrayDouble(p.counterHandle, &bufSize, &bufCount, &emptyBuf[0]) - if ret != win_pdh.PDH_MORE_DATA { - return nil, 0, fmt.Errorf("unable to collect data from counter. Error code is %x", ret) - } - - filledBuf := make([]win_pdh.PDH_FMT_COUNTERVALUE_ITEM_DOUBLE, bufCount*size) - ret = win_pdh.PdhGetFormattedCounterArrayDouble(p.counterHandle, &bufSize, &bufCount, &filledBuf[0]) - if ret != win_pdh.ERROR_SUCCESS { - return nil, 0, fmt.Errorf("unable to collect data from counter. Error code is %x", ret) - } - - return filledBuf, bufCount, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go deleted file mode 100644 index 80e9442f8..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/version.go +++ /dev/null @@ -1,86 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package winstats - -import ( - "fmt" - "golang.org/x/sys/windows/registry" -) - -// OSInfo is a convenience class for retrieving Windows OS information -type OSInfo struct { - BuildNumber, ProductName string - MajorVersion, MinorVersion, UBR uint64 -} - -// GetOSInfo reads Windows version information from the registry -func GetOSInfo() (*OSInfo, error) { - // for log detail - var keyPrefix string = `regedit:LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion` - - k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\Microsoft\Windows NT\CurrentVersion`, registry.QUERY_VALUE) - if err != nil { - return nil, fmt.Errorf("getOSInfo, open Windows %s failed: %w", keyPrefix, err) - } - defer k.Close() - - buildNumber, _, err := k.GetStringValue("CurrentBuildNumber") - if err != nil { - return nil, fmt.Errorf("getOSInfo, get %s\\CurrentBuildNumber failed: %w", keyPrefix, err) - } - - majorVersionNumber, _, err := k.GetIntegerValue("CurrentMajorVersionNumber") - if err != nil { - return nil, fmt.Errorf("getOSInfo, get %s\\CurrentMajorVersionNumber failed: %w", keyPrefix, err) - } - - minorVersionNumber, _, err := k.GetIntegerValue("CurrentMinorVersionNumber") - if err != nil { - return nil, fmt.Errorf("getOSInfo, get %s\\CurrentMinorVersionNumber failed: %w", keyPrefix, err) - } - - revision, _, err := k.GetIntegerValue("UBR") - if err != nil { - return nil, fmt.Errorf("getOSInfo, get %s\\UBR failed: %w", keyPrefix, err) - } - - productName, _, err := k.GetStringValue("ProductName") - if err != nil { - return nil, fmt.Errorf("getOSInfo, get %s\\ProductName failed: %w", keyPrefix, err) - } - - return &OSInfo{ - BuildNumber: buildNumber, - ProductName: productName, - MajorVersion: majorVersionNumber, - MinorVersion: minorVersionNumber, - UBR: revision, - }, nil -} - -// GetPatchVersion returns full OS version with patch -func (o *OSInfo) GetPatchVersion() string { - return fmt.Sprintf("%d.%d.%s.%d", o.MajorVersion, o.MinorVersion, o.BuildNumber, o.UBR) -} - -// GetBuild returns OS version upto build number -func (o *OSInfo) GetBuild() string { - return fmt.Sprintf("%d.%d.%s", o.MajorVersion, o.MinorVersion, o.BuildNumber) -} diff --git a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go b/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go deleted file mode 100644 index 84fe6212e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/kubelet/winstats/winstats.go +++ /dev/null @@ -1,188 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package winstats provides a client to get node and pod level stats on windows -package winstats - -import ( - "syscall" - "time" - "unsafe" - - cadvisorapi "github.com/google/cadvisor/info/v1" - cadvisorapiv2 "github.com/google/cadvisor/info/v2" -) - -var ( - procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW") -) - -// Client is an interface that is used to get stats information. -type Client interface { - WinContainerInfos() (map[string]cadvisorapiv2.ContainerInfo, error) - WinMachineInfo() (*cadvisorapi.MachineInfo, error) - WinVersionInfo() (*cadvisorapi.VersionInfo, error) - GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) -} - -// StatsClient is a client that implements the Client interface -type StatsClient struct { - client winNodeStatsClient -} - -type winNodeStatsClient interface { - startMonitoring() error - getNodeMetrics() (nodeMetrics, error) - getNodeInfo() nodeInfo - getMachineInfo() (*cadvisorapi.MachineInfo, error) - getVersionInfo() (*cadvisorapi.VersionInfo, error) -} - -type nodeMetrics struct { - cpuUsageCoreNanoSeconds uint64 - cpuUsageNanoCores uint64 - memoryPrivWorkingSetBytes uint64 - memoryCommittedBytes uint64 - timeStamp time.Time - interfaceStats []cadvisorapi.InterfaceStats -} - -type nodeInfo struct { - memoryPhysicalCapacityBytes uint64 - kernelVersion string - osImageVersion string - // startTime is the time when the node was started - startTime time.Time -} - -type cpuUsageCoreNanoSecondsCache struct { - latestValue uint64 - previousValue uint64 -} - -// newClient constructs a Client. -func newClient(statsNodeClient winNodeStatsClient) (Client, error) { - statsClient := new(StatsClient) - statsClient.client = statsNodeClient - - err := statsClient.client.startMonitoring() - if err != nil { - return nil, err - } - - return statsClient, nil -} - -// WinContainerInfos returns a map of container infos. The map contains node and -// pod level stats. Analogous to cadvisor GetContainerInfoV2 method. -func (c *StatsClient) WinContainerInfos() (map[string]cadvisorapiv2.ContainerInfo, error) { - infos := make(map[string]cadvisorapiv2.ContainerInfo) - rootContainerInfo, err := c.createRootContainerInfo() - if err != nil { - return nil, err - } - - infos["/"] = *rootContainerInfo - - return infos, nil -} - -// WinMachineInfo returns a cadvisorapi.MachineInfo with details about the -// node machine. Analogous to cadvisor MachineInfo method. -func (c *StatsClient) WinMachineInfo() (*cadvisorapi.MachineInfo, error) { - return c.client.getMachineInfo() -} - -// WinVersionInfo returns a cadvisorapi.VersionInfo with version info of -// the kernel and docker runtime. Analogous to cadvisor VersionInfo method. -func (c *StatsClient) WinVersionInfo() (*cadvisorapi.VersionInfo, error) { - return c.client.getVersionInfo() -} - -func (c *StatsClient) createRootContainerInfo() (*cadvisorapiv2.ContainerInfo, error) { - nodeMetrics, err := c.client.getNodeMetrics() - if err != nil { - return nil, err - } - - var stats []*cadvisorapiv2.ContainerStats - stats = append(stats, &cadvisorapiv2.ContainerStats{ - Timestamp: nodeMetrics.timeStamp, - Cpu: &cadvisorapi.CpuStats{ - Usage: cadvisorapi.CpuUsage{ - Total: nodeMetrics.cpuUsageCoreNanoSeconds, - }, - }, - CpuInst: &cadvisorapiv2.CpuInstStats{ - Usage: cadvisorapiv2.CpuInstUsage{ - Total: nodeMetrics.cpuUsageNanoCores, - }, - }, - Memory: &cadvisorapi.MemoryStats{ - WorkingSet: nodeMetrics.memoryPrivWorkingSetBytes, - Usage: nodeMetrics.memoryCommittedBytes, - }, - Network: &cadvisorapiv2.NetworkStats{ - Interfaces: nodeMetrics.interfaceStats, - }, - }) - - nodeInfo := c.client.getNodeInfo() - rootInfo := cadvisorapiv2.ContainerInfo{ - Spec: cadvisorapiv2.ContainerSpec{ - CreationTime: nodeInfo.startTime, - HasCpu: true, - HasMemory: true, - HasNetwork: true, - Memory: cadvisorapiv2.MemorySpec{ - Limit: nodeInfo.memoryPhysicalCapacityBytes, - }, - }, - Stats: stats, - } - - return &rootInfo, nil -} - -// GetDirFsInfo returns filesystem capacity and usage information. -func (c *StatsClient) GetDirFsInfo(path string) (cadvisorapiv2.FsInfo, error) { - var freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes int64 - var err error - - ret, _, err := syscall.Syscall6( - procGetDiskFreeSpaceEx.Addr(), - 4, - uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), - uintptr(unsafe.Pointer(&freeBytesAvailable)), - uintptr(unsafe.Pointer(&totalNumberOfBytes)), - uintptr(unsafe.Pointer(&totalNumberOfFreeBytes)), - 0, - 0, - ) - if ret == 0 { - return cadvisorapiv2.FsInfo{}, err - } - - return cadvisorapiv2.FsInfo{ - Timestamp: time.Now(), - Capacity: uint64(totalNumberOfBytes), - Available: uint64(freeBytesAvailable), - Usage: uint64(totalNumberOfBytes - freeBytesAvailable), - }, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go b/vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go deleted file mode 100644 index 7b02daff3..000000000 --- a/vendor/k8s.io/kubernetes/pkg/probe/dialer_others.go +++ /dev/null @@ -1,42 +0,0 @@ -//go:build !windows -// +build !windows - -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package probe - -import ( - "net" - "syscall" -) - -// ProbeDialer returns a dialer optimized for probes to avoid lingering sockets on TIME-WAIT state. -// The dialer reduces the TIME-WAIT period to 1 seconds instead of the OS default of 60 seconds. -// Using 1 second instead of 0 because SO_LINGER socket option to 0 causes pending data to be -// discarded and the connection to be aborted with an RST rather than for the pending data to be -// transmitted and the connection closed cleanly with a FIN. -// Ref: https://issues.k8s.io/89898 -func ProbeDialer() *net.Dialer { - dialer := &net.Dialer{ - Control: func(network, address string, c syscall.RawConn) error { - return c.Control(func(fd uintptr) { - syscall.SetsockoptLinger(int(fd), syscall.SOL_SOCKET, syscall.SO_LINGER, &syscall.Linger{Onoff: 1, Linger: 1}) - }) - }, - } - return dialer -} diff --git a/vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go b/vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go deleted file mode 100644 index ab0d02047..000000000 --- a/vendor/k8s.io/kubernetes/pkg/probe/dialer_windows.go +++ /dev/null @@ -1,42 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package probe - -import ( - "net" - "syscall" -) - -// ProbeDialer returns a dialer optimized for probes to avoid lingering sockets on TIME-WAIT state. -// The dialer reduces the TIME-WAIT period to 1 seconds instead of the OS default of 60 seconds. -// Using 1 second instead of 0 because SO_LINGER socket option to 0 causes pending data to be -// discarded and the connection to be aborted with an RST rather than for the pending data to be -// transmitted and the connection closed cleanly with a FIN. -// Ref: https://issues.k8s.io/89898 -func ProbeDialer() *net.Dialer { - dialer := &net.Dialer{ - Control: func(network, address string, c syscall.RawConn) error { - return c.Control(func(fd uintptr) { - syscall.SetsockoptLinger(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_LINGER, &syscall.Linger{Onoff: 1, Linger: 1}) - }) - }, - } - return dialer -} diff --git a/vendor/k8s.io/kubernetes/pkg/probe/doc.go b/vendor/k8s.io/kubernetes/pkg/probe/doc.go deleted file mode 100644 index 89c70b2c1..000000000 --- a/vendor/k8s.io/kubernetes/pkg/probe/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package probe contains utilities for health probing, as well as health status information. -package probe diff --git a/vendor/k8s.io/kubernetes/pkg/probe/http/http.go b/vendor/k8s.io/kubernetes/pkg/probe/http/http.go deleted file mode 100644 index 20e33da8e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/probe/http/http.go +++ /dev/null @@ -1,141 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package http - -import ( - "crypto/tls" - "errors" - "fmt" - "net/http" - "time" - - utilnet "k8s.io/apimachinery/pkg/util/net" - "k8s.io/kubernetes/pkg/probe" - - "k8s.io/klog/v2" - utilio "k8s.io/utils/io" -) - -const ( - maxRespBodyLength = 10 * 1 << 10 // 10KB -) - -// New creates Prober that will skip TLS verification while probing. -// followNonLocalRedirects configures whether the prober should follow redirects to a different hostname. -// If disabled, redirects to other hosts will trigger a warning result. -func New(followNonLocalRedirects bool) Prober { - tlsConfig := &tls.Config{InsecureSkipVerify: true} - return NewWithTLSConfig(tlsConfig, followNonLocalRedirects) -} - -// NewWithTLSConfig takes tls config as parameter. -// followNonLocalRedirects configures whether the prober should follow redirects to a different hostname. -// If disabled, redirects to other hosts will trigger a warning result. -func NewWithTLSConfig(config *tls.Config, followNonLocalRedirects bool) Prober { - // We do not want the probe use node's local proxy set. - transport := utilnet.SetTransportDefaults( - &http.Transport{ - TLSClientConfig: config, - DisableKeepAlives: true, - Proxy: http.ProxyURL(nil), - DisableCompression: true, // removes Accept-Encoding header - // DialContext creates unencrypted TCP connections - // and is also used by the transport for HTTPS connection - DialContext: probe.ProbeDialer().DialContext, - }) - - return httpProber{transport, followNonLocalRedirects} -} - -// Prober is an interface that defines the Probe function for doing HTTP readiness/liveness checks. -type Prober interface { - Probe(req *http.Request, timeout time.Duration) (probe.Result, string, error) -} - -type httpProber struct { - transport *http.Transport - followNonLocalRedirects bool -} - -// Probe returns a ProbeRunner capable of running an HTTP check. -func (pr httpProber) Probe(req *http.Request, timeout time.Duration) (probe.Result, string, error) { - client := &http.Client{ - Timeout: timeout, - Transport: pr.transport, - CheckRedirect: RedirectChecker(pr.followNonLocalRedirects), - } - return DoHTTPProbe(req, client) -} - -// GetHTTPInterface is an interface for making HTTP requests, that returns a response and error. -type GetHTTPInterface interface { - Do(req *http.Request) (*http.Response, error) -} - -// DoHTTPProbe checks if a GET request to the url succeeds. -// If the HTTP response code is successful (i.e. 400 > code >= 200), it returns Success. -// If the HTTP response code is unsuccessful or HTTP communication fails, it returns Failure. -// This is exported because some other packages may want to do direct HTTP probes. -func DoHTTPProbe(req *http.Request, client GetHTTPInterface) (probe.Result, string, error) { - url := req.URL - headers := req.Header - res, err := client.Do(req) - if err != nil { - // Convert errors into failures to catch timeouts. - return probe.Failure, err.Error(), nil - } - defer res.Body.Close() - b, err := utilio.ReadAtMost(res.Body, maxRespBodyLength) - if err != nil { - if err == utilio.ErrLimitReached { - klog.V(4).Infof("Non fatal body truncation for %s, Response: %v", url.String(), *res) - } else { - return probe.Failure, "", err - } - } - body := string(b) - if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest { - if res.StatusCode >= http.StatusMultipleChoices { // Redirect - klog.V(4).Infof("Probe terminated redirects for %s, Response: %v", url.String(), *res) - return probe.Warning, fmt.Sprintf("Probe terminated redirects, Response body: %v", body), nil - } - klog.V(4).Infof("Probe succeeded for %s, Response: %v", url.String(), *res) - return probe.Success, body, nil - } - klog.V(4).Infof("Probe failed for %s with request headers %v, response body: %v", url.String(), headers, body) - // Note: Until https://issue.k8s.io/99425 is addressed, this user-facing failure message must not contain the response body. - failureMsg := fmt.Sprintf("HTTP probe failed with statuscode: %d", res.StatusCode) - return probe.Failure, failureMsg, nil -} - -// RedirectChecker returns a function that can be used to check HTTP redirects. -func RedirectChecker(followNonLocalRedirects bool) func(*http.Request, []*http.Request) error { - if followNonLocalRedirects { - return nil // Use the default http client checker. - } - - return func(req *http.Request, via []*http.Request) error { - if req.URL.Hostname() != via[0].URL.Hostname() { - return http.ErrUseLastResponse - } - // Default behavior: stop after 10 redirects. - if len(via) >= 10 { - return errors.New("stopped after 10 redirects") - } - return nil - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/probe/http/request.go b/vendor/k8s.io/kubernetes/pkg/probe/http/request.go deleted file mode 100644 index fb7f818b2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/probe/http/request.go +++ /dev/null @@ -1,119 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package http - -import ( - "fmt" - "net" - "net/http" - "net/url" - "strconv" - "strings" - - v1 "k8s.io/api/core/v1" - "k8s.io/component-base/version" - "k8s.io/kubernetes/pkg/probe" -) - -// NewProbeRequest returns an http.Request suitable for use as a request for a -// probe. -func NewProbeRequest(url *url.URL, headers http.Header) (*http.Request, error) { - return newProbeRequest(url, headers, "probe") -} - -// NewRequestForHTTPGetAction returns an http.Request derived from httpGet. -// When httpGet.Host is empty, podIP will be used instead. -func NewRequestForHTTPGetAction(httpGet *v1.HTTPGetAction, container *v1.Container, podIP string, userAgentFragment string) (*http.Request, error) { - scheme := strings.ToLower(string(httpGet.Scheme)) - if scheme == "" { - scheme = "http" - } - - host := httpGet.Host - if host == "" { - host = podIP - } - - port, err := probe.ResolveContainerPort(httpGet.Port, container) - if err != nil { - return nil, err - } - - path := httpGet.Path - url := formatURL(scheme, host, port, path) - headers := v1HeaderToHTTPHeader(httpGet.HTTPHeaders) - - return newProbeRequest(url, headers, userAgentFragment) -} - -func newProbeRequest(url *url.URL, headers http.Header, userAgentFragment string) (*http.Request, error) { - req, err := http.NewRequest("GET", url.String(), nil) - if err != nil { - return nil, err - } - - if headers == nil { - headers = http.Header{} - } - if _, ok := headers["User-Agent"]; !ok { - // User-Agent header was not defined, set it - headers.Set("User-Agent", userAgent(userAgentFragment)) - } - if _, ok := headers["Accept"]; !ok { - // Accept header was not defined. accept all - headers.Set("Accept", "*/*") - } else if headers.Get("Accept") == "" { - // Accept header was overridden but is empty. removing - headers.Del("Accept") - } - req.Header = headers - req.Host = headers.Get("Host") - - return req, nil -} - -func userAgent(purpose string) string { - v := version.Get() - return fmt.Sprintf("kube-%s/%s.%s", purpose, v.Major, v.Minor) -} - -// formatURL formats a URL from args. For testability. -func formatURL(scheme string, host string, port int, path string) *url.URL { - u, err := url.Parse(path) - // Something is busted with the path, but it's too late to reject it. Pass it along as is. - // - // This construction of a URL may be wrong in some cases, but it preserves - // legacy prober behavior. - if err != nil { - u = &url.URL{ - Path: path, - } - } - u.Scheme = scheme - u.Host = net.JoinHostPort(host, strconv.Itoa(port)) - return u -} - -// v1HeaderToHTTPHeader takes a list of HTTPHeader string pairs -// and returns a populated string->[]string http.Header map. -func v1HeaderToHTTPHeader(headerList []v1.HTTPHeader) http.Header { - headers := make(http.Header) - for _, header := range headerList { - headers.Add(header.Name, header.Value) - } - return headers -} diff --git a/vendor/k8s.io/kubernetes/pkg/probe/probe.go b/vendor/k8s.io/kubernetes/pkg/probe/probe.go deleted file mode 100644 index c47b6c2fe..000000000 --- a/vendor/k8s.io/kubernetes/pkg/probe/probe.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package probe - -// Result is a string used to handle the results for probing container readiness/liveness -type Result string - -const ( - // Success Result - Success Result = "success" - // Warning Result. Logically success, but with additional debugging information attached. - Warning Result = "warning" - // Failure Result - Failure Result = "failure" - // Unknown Result - Unknown Result = "unknown" -) diff --git a/vendor/k8s.io/kubernetes/pkg/probe/util.go b/vendor/k8s.io/kubernetes/pkg/probe/util.go deleted file mode 100644 index cb2512874..000000000 --- a/vendor/k8s.io/kubernetes/pkg/probe/util.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package probe - -import ( - "fmt" - "strconv" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/intstr" -) - -func ResolveContainerPort(param intstr.IntOrString, container *v1.Container) (int, error) { - port := -1 - var err error - switch param.Type { - case intstr.Int: - port = param.IntValue() - case intstr.String: - if port, err = findPortByName(container, param.StrVal); err != nil { - // Last ditch effort - maybe it was an int stored as string? - if port, err = strconv.Atoi(param.StrVal); err != nil { - return port, err - } - } - default: - return port, fmt.Errorf("intOrString had no kind: %+v", param) - } - if port > 0 && port < 65536 { - return port, nil - } - return port, fmt.Errorf("invalid port number: %v", port) -} - -// findPortByName is a helper function to look up a port in a container by name. -func findPortByName(container *v1.Container, portName string) (int, error) { - for _, port := range container.Ports { - if port.Name == portName { - return int(port.ContainerPort), nil - } - } - return 0, fmt.Errorf("port %s not found", portName) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/OWNERS b/vendor/k8s.io/kubernetes/pkg/scheduler/OWNERS deleted file mode 100644 index 19c02ee0b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - sig-scheduling-maintainers -reviewers: - - sig-scheduling -labels: - - sig/scheduling diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/OWNERS b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/OWNERS deleted file mode 100644 index 3023c572e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/OWNERS +++ /dev/null @@ -1,11 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - api-approvers -reviewers: - - api-reviewers - - sig-scheduling-api-reviewers - - sig-scheduling-api-approvers -labels: - - kind/api-change - - sig/scheduling diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/doc.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/doc.go deleted file mode 100644 index ac48d0307..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/doc.go +++ /dev/null @@ -1,20 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// +k8s:deepcopy-gen=package -// +groupName=kubescheduler.config.k8s.io - -package config diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/register.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/register.go deleted file mode 100644 index 457556e10..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/register.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/schema" -) - -// GroupName is the group name used in this package -const GroupName = "kubescheduler.config.k8s.io" - -// SchemeGroupVersion is group version used to register these objects -var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} - -var ( - // SchemeBuilder is the scheme builder with scheme init functions to run for this API package - SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) - // AddToScheme is a global function that registers this API group & version to a scheme - AddToScheme = SchemeBuilder.AddToScheme -) - -// addKnownTypes registers known types to the given scheme -func addKnownTypes(scheme *runtime.Scheme) error { - scheme.AddKnownTypes(SchemeGroupVersion, - &KubeSchedulerConfiguration{}, - &DefaultPreemptionArgs{}, - &InterPodAffinityArgs{}, - &NodeResourcesFitArgs{}, - &PodTopologySpreadArgs{}, - &VolumeBindingArgs{}, - &NodeResourcesBalancedAllocationArgs{}, - &NodeAffinityArgs{}, - ) - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/scheme/scheme.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/scheme/scheme.go deleted file mode 100644 index 366f776bf..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/scheme/scheme.go +++ /dev/null @@ -1,46 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package scheme - -import ( - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/runtime/serializer" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - config "k8s.io/kubernetes/pkg/scheduler/apis/config" - configv1 "k8s.io/kubernetes/pkg/scheduler/apis/config/v1" -) - -var ( - // Scheme is the runtime.Scheme to which all kubescheduler api types are registered. - Scheme = runtime.NewScheme() - - // Codecs provides access to encoding and decoding for the scheme. - Codecs = serializer.NewCodecFactory(Scheme, serializer.EnableStrict) -) - -func init() { - AddToScheme(Scheme) -} - -// AddToScheme builds the kubescheduler scheme using all known versions of the kubescheduler api. -func AddToScheme(scheme *runtime.Scheme) { - utilruntime.Must(config.AddToScheme(scheme)) - utilruntime.Must(configv1.AddToScheme(scheme)) - utilruntime.Must(scheme.SetVersionPriority( - configv1.SchemeGroupVersion, - )) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go deleted file mode 100644 index b0c94a18e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types.go +++ /dev/null @@ -1,336 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - "math" - - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/sets" - componentbaseconfig "k8s.io/component-base/config" -) - -const ( - // DefaultKubeSchedulerPort is the default port for the scheduler status server. - // May be overridden by a flag at startup. - DefaultKubeSchedulerPort = 10259 -) - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// KubeSchedulerConfiguration configures a scheduler -type KubeSchedulerConfiguration struct { - // TypeMeta contains the API version and kind. In kube-scheduler, after - // conversion from the versioned KubeSchedulerConfiguration type to this - // internal type, we set the APIVersion field to the scheme group/version of - // the type we converted from. This is done in cmd/kube-scheduler in two - // places: (1) when loading config from a file, (2) generating the default - // config. Based on the versioned type set in this field, we make decisions; - // for example (1) during validation to check for usage of removed plugins, - // (2) writing config to a file, (3) initialising the scheduler. - metav1.TypeMeta - - // Parallelism defines the amount of parallelism in algorithms for scheduling a Pods. Must be greater than 0. Defaults to 16 - Parallelism int32 - - // LeaderElection defines the configuration of leader election client. - LeaderElection componentbaseconfig.LeaderElectionConfiguration - - // ClientConnection specifies the kubeconfig file and client connection - // settings for the proxy server to use when communicating with the apiserver. - ClientConnection componentbaseconfig.ClientConnectionConfiguration - - // DebuggingConfiguration holds configuration for Debugging related features - // TODO: We might wanna make this a substruct like Debugging componentbaseconfig.DebuggingConfiguration - componentbaseconfig.DebuggingConfiguration - - // PercentageOfNodesToScore is the percentage of all nodes that once found feasible - // for running a pod, the scheduler stops its search for more feasible nodes in - // the cluster. This helps improve scheduler's performance. Scheduler always tries to find - // at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is. - // Example: if the cluster size is 500 nodes and the value of this flag is 30, - // then scheduler stops finding further feasible nodes once it finds 150 feasible ones. - // When the value is 0, default percentage (5%--50% based on the size of the cluster) of the - // nodes will be scored. It is overridden by profile level PercentageOfNodesToScore. - PercentageOfNodesToScore *int32 - - // PodInitialBackoffSeconds is the initial backoff for unschedulable pods. - // If specified, it must be greater than 0. If this value is null, the default value (1s) - // will be used. - PodInitialBackoffSeconds int64 - - // PodMaxBackoffSeconds is the max backoff for unschedulable pods. - // If specified, it must be greater than or equal to podInitialBackoffSeconds. If this value is null, - // the default value (10s) will be used. - PodMaxBackoffSeconds int64 - - // Profiles are scheduling profiles that kube-scheduler supports. Pods can - // choose to be scheduled under a particular profile by setting its associated - // scheduler name. Pods that don't specify any scheduler name are scheduled - // with the "default-scheduler" profile, if present here. - Profiles []KubeSchedulerProfile - - // Extenders are the list of scheduler extenders, each holding the values of how to communicate - // with the extender. These extenders are shared by all scheduler profiles. - Extenders []Extender - - // DelayCacheUntilActive specifies when to start caching. If this is true and leader election is enabled, - // the scheduler will wait to fill informer caches until it is the leader. Doing so will have slower - // failover with the benefit of lower memory overhead while waiting to become leader. - // Defaults to false. - DelayCacheUntilActive bool -} - -// KubeSchedulerProfile is a scheduling profile. -type KubeSchedulerProfile struct { - // SchedulerName is the name of the scheduler associated to this profile. - // If SchedulerName matches with the pod's "spec.schedulerName", then the pod - // is scheduled with this profile. - SchedulerName string - - // PercentageOfNodesToScore is the percentage of all nodes that once found feasible - // for running a pod, the scheduler stops its search for more feasible nodes in - // the cluster. This helps improve scheduler's performance. Scheduler always tries to find - // at least "minFeasibleNodesToFind" feasible nodes no matter what the value of this flag is. - // Example: if the cluster size is 500 nodes and the value of this flag is 30, - // then scheduler stops finding further feasible nodes once it finds 150 feasible ones. - // When the value is 0, default percentage (5%--50% based on the size of the cluster) of the - // nodes will be scored. It will override global PercentageOfNodesToScore. If it is empty, - // global PercentageOfNodesToScore will be used. - PercentageOfNodesToScore *int32 - - // Plugins specify the set of plugins that should be enabled or disabled. - // Enabled plugins are the ones that should be enabled in addition to the - // default plugins. Disabled plugins are any of the default plugins that - // should be disabled. - // When no enabled or disabled plugin is specified for an extension point, - // default plugins for that extension point will be used if there is any. - // If a QueueSort plugin is specified, the same QueueSort Plugin and - // PluginConfig must be specified for all profiles. - Plugins *Plugins - - // PluginConfig is an optional set of custom plugin arguments for each plugin. - // Omitting config args for a plugin is equivalent to using the default config - // for that plugin. - PluginConfig []PluginConfig -} - -// Plugins include multiple extension points. When specified, the list of plugins for -// a particular extension point are the only ones enabled. If an extension point is -// omitted from the config, then the default set of plugins is used for that extension point. -// Enabled plugins are called in the order specified here, after default plugins. If they need to -// be invoked before default plugins, default plugins must be disabled and re-enabled here in desired order. -type Plugins struct { - // PreEnqueue is a list of plugins that should be invoked before adding pods to the scheduling queue. - PreEnqueue PluginSet - - // QueueSort is a list of plugins that should be invoked when sorting pods in the scheduling queue. - QueueSort PluginSet - - // PreFilter is a list of plugins that should be invoked at "PreFilter" extension point of the scheduling framework. - PreFilter PluginSet - - // Filter is a list of plugins that should be invoked when filtering out nodes that cannot run the Pod. - Filter PluginSet - - // PostFilter is a list of plugins that are invoked after filtering phase, but only when no feasible nodes were found for the pod. - PostFilter PluginSet - - // PreScore is a list of plugins that are invoked before scoring. - PreScore PluginSet - - // Score is a list of plugins that should be invoked when ranking nodes that have passed the filtering phase. - Score PluginSet - - // Reserve is a list of plugins invoked when reserving/unreserving resources - // after a node is assigned to run the pod. - Reserve PluginSet - - // Permit is a list of plugins that control binding of a Pod. These plugins can prevent or delay binding of a Pod. - Permit PluginSet - - // PreBind is a list of plugins that should be invoked before a pod is bound. - PreBind PluginSet - - // Bind is a list of plugins that should be invoked at "Bind" extension point of the scheduling framework. - // The scheduler call these plugins in order. Scheduler skips the rest of these plugins as soon as one returns success. - Bind PluginSet - - // PostBind is a list of plugins that should be invoked after a pod is successfully bound. - PostBind PluginSet - - // MultiPoint is a simplified config field for enabling plugins for all valid extension points - MultiPoint PluginSet -} - -// PluginSet specifies enabled and disabled plugins for an extension point. -// If an array is empty, missing, or nil, default plugins at that extension point will be used. -type PluginSet struct { - // Enabled specifies plugins that should be enabled in addition to default plugins. - // These are called after default plugins and in the same order specified here. - Enabled []Plugin - // Disabled specifies default plugins that should be disabled. - // When all default plugins need to be disabled, an array containing only one "*" should be provided. - Disabled []Plugin -} - -// Plugin specifies a plugin name and its weight when applicable. Weight is used only for Score plugins. -type Plugin struct { - // Name defines the name of plugin - Name string - // Weight defines the weight of plugin, only used for Score plugins. - Weight int32 -} - -// PluginConfig specifies arguments that should be passed to a plugin at the time of initialization. -// A plugin that is invoked at multiple extension points is initialized once. Args can have arbitrary structure. -// It is up to the plugin to process these Args. -type PluginConfig struct { - // Name defines the name of plugin being configured - Name string - // Args defines the arguments passed to the plugins at the time of initialization. Args can have arbitrary structure. - Args runtime.Object -} - -/* - * NOTE: The following variables and methods are intentionally left out of the staging mirror. - */ -const ( - // DefaultPercentageOfNodesToScore defines the percentage of nodes of all nodes - // that once found feasible, the scheduler stops looking for more nodes. - // A value of 0 means adaptive, meaning the scheduler figures out a proper default. - DefaultPercentageOfNodesToScore = 0 - - // MaxCustomPriorityScore is the max score UtilizationShapePoint expects. - MaxCustomPriorityScore int64 = 10 - - // MaxTotalScore is the maximum total score. - MaxTotalScore int64 = math.MaxInt64 - - // MaxWeight defines the max weight value allowed for custom PriorityPolicy - MaxWeight = MaxTotalScore / MaxCustomPriorityScore -) - -// Names returns the list of enabled plugin names. -func (p *Plugins) Names() []string { - if p == nil { - return nil - } - extensions := []PluginSet{ - p.PreEnqueue, - p.PreFilter, - p.Filter, - p.PostFilter, - p.Reserve, - p.PreScore, - p.Score, - p.PreBind, - p.Bind, - p.PostBind, - p.Permit, - p.QueueSort, - } - n := sets.New[string]() - for _, e := range extensions { - for _, pg := range e.Enabled { - n.Insert(pg.Name) - } - } - return sets.List(n) -} - -// Extender holds the parameters used to communicate with the extender. If a verb is unspecified/empty, -// it is assumed that the extender chose not to provide that extension. -type Extender struct { - // URLPrefix at which the extender is available - URLPrefix string - // Verb for the filter call, empty if not supported. This verb is appended to the URLPrefix when issuing the filter call to extender. - FilterVerb string - // Verb for the preempt call, empty if not supported. This verb is appended to the URLPrefix when issuing the preempt call to extender. - PreemptVerb string - // Verb for the prioritize call, empty if not supported. This verb is appended to the URLPrefix when issuing the prioritize call to extender. - PrioritizeVerb string - // The numeric multiplier for the node scores that the prioritize call generates. - // The weight should be a positive integer - Weight int64 - // Verb for the bind call, empty if not supported. This verb is appended to the URLPrefix when issuing the bind call to extender. - // If this method is implemented by the extender, it is the extender's responsibility to bind the pod to apiserver. Only one extender - // can implement this function. - BindVerb string - // EnableHTTPS specifies whether https should be used to communicate with the extender - EnableHTTPS bool - // TLSConfig specifies the transport layer security config - TLSConfig *ExtenderTLSConfig - // HTTPTimeout specifies the timeout duration for a call to the extender. Filter timeout fails the scheduling of the pod. Prioritize - // timeout is ignored, k8s/other extenders priorities are used to select the node. - HTTPTimeout metav1.Duration - // NodeCacheCapable specifies that the extender is capable of caching node information, - // so the scheduler should only send minimal information about the eligible nodes - // assuming that the extender already cached full details of all nodes in the cluster - NodeCacheCapable bool - // ManagedResources is a list of extended resources that are managed by - // this extender. - // - A pod will be sent to the extender on the Filter, Prioritize and Bind - // (if the extender is the binder) phases iff the pod requests at least - // one of the extended resources in this list. If empty or unspecified, - // all pods will be sent to this extender. - // - If IgnoredByScheduler is set to true for a resource, kube-scheduler - // will skip checking the resource in predicates. - // +optional - ManagedResources []ExtenderManagedResource - // Ignorable specifies if the extender is ignorable, i.e. scheduling should not - // fail when the extender returns an error or is not reachable. - Ignorable bool -} - -// ExtenderManagedResource describes the arguments of extended resources -// managed by an extender. -type ExtenderManagedResource struct { - // Name is the extended resource name. - Name string - // IgnoredByScheduler indicates whether kube-scheduler should ignore this - // resource when applying predicates. - IgnoredByScheduler bool -} - -// ExtenderTLSConfig contains settings to enable TLS with extender -type ExtenderTLSConfig struct { - // Server should be accessed without verifying the TLS certificate. For testing only. - Insecure bool - // ServerName is passed to the server for SNI and is used in the client to check server - // certificates against. If ServerName is empty, the hostname used to contact the - // server is used. - ServerName string - - // Server requires TLS client certificate authentication - CertFile string - // Server requires TLS client certificate authentication - KeyFile string - // Trusted root certificates for server - CAFile string - - // CertData holds PEM-encoded bytes (typically read from a client certificate file). - // CertData takes precedence over CertFile - CertData []byte - // KeyData holds PEM-encoded bytes (typically read from a client certificate key file). - // KeyData takes precedence over KeyFile - KeyData []byte `datapolicy:"security-key"` - // CAData holds PEM-encoded bytes (typically read from a root certificates bundle). - // CAData takes precedence over CAFile - CAData []byte -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types_pluginargs.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types_pluginargs.go deleted file mode 100644 index a3db9a904..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/types_pluginargs.go +++ /dev/null @@ -1,218 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package config - -import ( - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// DefaultPreemptionArgs holds arguments used to configure the -// DefaultPreemption plugin. -type DefaultPreemptionArgs struct { - metav1.TypeMeta - - // MinCandidateNodesPercentage is the minimum number of candidates to - // shortlist when dry running preemption as a percentage of number of nodes. - // Must be in the range [0, 100]. Defaults to 10% of the cluster size if - // unspecified. - MinCandidateNodesPercentage int32 - // MinCandidateNodesAbsolute is the absolute minimum number of candidates to - // shortlist. The likely number of candidates enumerated for dry running - // preemption is given by the formula: - // numCandidates = max(numNodes * minCandidateNodesPercentage, minCandidateNodesAbsolute) - // We say "likely" because there are other factors such as PDB violations - // that play a role in the number of candidates shortlisted. Must be at least - // 0 nodes. Defaults to 100 nodes if unspecified. - MinCandidateNodesAbsolute int32 -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// InterPodAffinityArgs holds arguments used to configure the InterPodAffinity plugin. -type InterPodAffinityArgs struct { - metav1.TypeMeta - - // HardPodAffinityWeight is the scoring weight for existing pods with a - // matching hard affinity to the incoming pod. - HardPodAffinityWeight int32 - - // IgnorePreferredTermsOfExistingPods configures the scheduler to ignore existing pods' preferred affinity - // rules when scoring candidate nodes, unless the incoming pod has inter-pod affinities. - IgnorePreferredTermsOfExistingPods bool -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// NodeResourcesFitArgs holds arguments used to configure the NodeResourcesFit plugin. -type NodeResourcesFitArgs struct { - metav1.TypeMeta - - // IgnoredResources is the list of resources that NodeResources fit filter - // should ignore. - IgnoredResources []string - // IgnoredResourceGroups defines the list of resource groups that NodeResources fit filter should ignore. - // e.g. if group is ["example.com"], it will ignore all resource names that begin - // with "example.com", such as "example.com/aaa" and "example.com/bbb". - // A resource group name can't contain '/'. - IgnoredResourceGroups []string - - // ScoringStrategy selects the node resource scoring strategy. - ScoringStrategy *ScoringStrategy -} - -// PodTopologySpreadConstraintsDefaulting defines how to set default constraints -// for the PodTopologySpread plugin. -type PodTopologySpreadConstraintsDefaulting string - -const ( - // SystemDefaulting instructs to use the kubernetes defined default. - SystemDefaulting PodTopologySpreadConstraintsDefaulting = "System" - // ListDefaulting instructs to use the config provided default. - ListDefaulting PodTopologySpreadConstraintsDefaulting = "List" -) - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// PodTopologySpreadArgs holds arguments used to configure the PodTopologySpread plugin. -type PodTopologySpreadArgs struct { - metav1.TypeMeta - - // DefaultConstraints defines topology spread constraints to be applied to - // Pods that don't define any in `pod.spec.topologySpreadConstraints`. - // `.defaultConstraints[*].labelSelectors` must be empty, as they are - // deduced from the Pod's membership to Services, ReplicationControllers, - // ReplicaSets or StatefulSets. - // When not empty, .defaultingType must be "List". - DefaultConstraints []v1.TopologySpreadConstraint - - // DefaultingType determines how .defaultConstraints are deduced. Can be one - // of "System" or "List". - // - // - "System": Use kubernetes defined constraints that spread Pods among - // Nodes and Zones. - // - "List": Use constraints defined in .defaultConstraints. - // - // Defaults to "System". - // +optional - DefaultingType PodTopologySpreadConstraintsDefaulting -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// NodeResourcesBalancedAllocationArgs holds arguments used to configure NodeResourcesBalancedAllocation plugin. -type NodeResourcesBalancedAllocationArgs struct { - metav1.TypeMeta - - // Resources to be considered when scoring. - // The default resource set includes "cpu" and "memory", only valid weight is 1. - Resources []ResourceSpec -} - -// UtilizationShapePoint represents a single point of a priority function shape. -type UtilizationShapePoint struct { - // Utilization (x axis). Valid values are 0 to 100. Fully utilized node maps to 100. - Utilization int32 - // Score assigned to a given utilization (y axis). Valid values are 0 to 10. - Score int32 -} - -// ResourceSpec represents single resource. -type ResourceSpec struct { - // Name of the resource. - Name string - // Weight of the resource. - Weight int64 -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// VolumeBindingArgs holds arguments used to configure the VolumeBinding plugin. -type VolumeBindingArgs struct { - metav1.TypeMeta - - // BindTimeoutSeconds is the timeout in seconds in volume binding operation. - // Value must be non-negative integer. The value zero indicates no waiting. - // If this value is nil, the default value will be used. - BindTimeoutSeconds int64 - - // Shape specifies the points defining the score function shape, which is - // used to score nodes based on the utilization of statically provisioned - // PVs. The utilization is calculated by dividing the total requested - // storage of the pod by the total capacity of feasible PVs on each node. - // Each point contains utilization (ranges from 0 to 100) and its - // associated score (ranges from 0 to 10). You can turn the priority by - // specifying different scores for different utilization numbers. - // The default shape points are: - // 1) 0 for 0 utilization - // 2) 10 for 100 utilization - // All points must be sorted in increasing order by utilization. - // +featureGate=StorageCapacityScoring - // +optional - Shape []UtilizationShapePoint -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object - -// NodeAffinityArgs holds arguments to configure the NodeAffinity plugin. -type NodeAffinityArgs struct { - metav1.TypeMeta - - // AddedAffinity is applied to all Pods additionally to the NodeAffinity - // specified in the PodSpec. That is, Nodes need to satisfy AddedAffinity - // AND .spec.NodeAffinity. AddedAffinity is empty by default (all Nodes - // match). - // When AddedAffinity is used, some Pods with affinity requirements that match - // a specific Node (such as Daemonset Pods) might remain unschedulable. - AddedAffinity *v1.NodeAffinity -} - -// ScoringStrategyType the type of scoring strategy used in NodeResourcesFit plugin. -type ScoringStrategyType string - -const ( - // LeastAllocated strategy prioritizes nodes with least allocated resources. - LeastAllocated ScoringStrategyType = "LeastAllocated" - // MostAllocated strategy prioritizes nodes with most allocated resources. - MostAllocated ScoringStrategyType = "MostAllocated" - // RequestedToCapacityRatio strategy allows specifying a custom shape function - // to score nodes based on the request to capacity ratio. - RequestedToCapacityRatio ScoringStrategyType = "RequestedToCapacityRatio" -) - -// ScoringStrategy define ScoringStrategyType for node resource plugin -type ScoringStrategy struct { - // Type selects which strategy to run. - Type ScoringStrategyType - - // Resources to consider when scoring. - // The default resource set includes "cpu" and "memory" with an equal weight. - // Allowed weights go from 1 to 100. - // Weight defaults to 1 if not specified or explicitly set to 0. - Resources []ResourceSpec - - // Arguments specific to RequestedToCapacityRatio strategy. - RequestedToCapacityRatio *RequestedToCapacityRatioParam -} - -// RequestedToCapacityRatioParam define RequestedToCapacityRatio parameters -type RequestedToCapacityRatioParam struct { - // Shape is a list of points defining the scoring function shape. - Shape []UtilizationShapePoint -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/conversion.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/conversion.go deleted file mode 100644 index 18115f93f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/conversion.go +++ /dev/null @@ -1,107 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1 - -import ( - "fmt" - "sync" - - "k8s.io/apimachinery/pkg/conversion" - "k8s.io/apimachinery/pkg/runtime" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - v1 "k8s.io/kube-scheduler/config/v1" - "k8s.io/kubernetes/pkg/scheduler/apis/config" -) - -var ( - // pluginArgConversionScheme is a scheme with internal and v1 registered, - // used for defaulting/converting typed PluginConfig Args. - // Access via getPluginArgConversionScheme() - pluginArgConversionScheme *runtime.Scheme - initPluginArgConversionScheme sync.Once -) - -func GetPluginArgConversionScheme() *runtime.Scheme { - initPluginArgConversionScheme.Do(func() { - // set up the scheme used for plugin arg conversion - pluginArgConversionScheme = runtime.NewScheme() - utilruntime.Must(AddToScheme(pluginArgConversionScheme)) - utilruntime.Must(config.AddToScheme(pluginArgConversionScheme)) - }) - return pluginArgConversionScheme -} - -func Convert_v1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(in *v1.KubeSchedulerConfiguration, out *config.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := autoConvert_v1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(in, out, s); err != nil { - return err - } - return convertToInternalPluginConfigArgs(out) -} - -// convertToInternalPluginConfigArgs converts PluginConfig#Args into internal -// types using a scheme, after applying defaults. -func convertToInternalPluginConfigArgs(out *config.KubeSchedulerConfiguration) error { - scheme := GetPluginArgConversionScheme() - for i := range out.Profiles { - prof := &out.Profiles[i] - for j := range prof.PluginConfig { - args := prof.PluginConfig[j].Args - if args == nil { - continue - } - if _, isUnknown := args.(*runtime.Unknown); isUnknown { - continue - } - internalArgs, err := scheme.ConvertToVersion(args, config.SchemeGroupVersion) - if err != nil { - return fmt.Errorf("converting .Profiles[%d].PluginConfig[%d].Args into internal type: %w", i, j, err) - } - prof.PluginConfig[j].Args = internalArgs - } - } - return nil -} - -func Convert_config_KubeSchedulerConfiguration_To_v1_KubeSchedulerConfiguration(in *config.KubeSchedulerConfiguration, out *v1.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := autoConvert_config_KubeSchedulerConfiguration_To_v1_KubeSchedulerConfiguration(in, out, s); err != nil { - return err - } - return convertToExternalPluginConfigArgs(out) -} - -// convertToExternalPluginConfigArgs converts PluginConfig#Args into -// external (versioned) types using a scheme. -func convertToExternalPluginConfigArgs(out *v1.KubeSchedulerConfiguration) error { - scheme := GetPluginArgConversionScheme() - for i := range out.Profiles { - for j := range out.Profiles[i].PluginConfig { - args := out.Profiles[i].PluginConfig[j].Args - if args.Object == nil { - continue - } - if _, isUnknown := args.Object.(*runtime.Unknown); isUnknown { - continue - } - externalArgs, err := scheme.ConvertToVersion(args.Object, SchemeGroupVersion) - if err != nil { - return err - } - out.Profiles[i].PluginConfig[j].Args.Object = externalArgs - } - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go deleted file mode 100644 index baad8cd0f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/default_plugins.go +++ /dev/null @@ -1,157 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1 - -import ( - "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - v1 "k8s.io/kube-scheduler/config/v1" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/utils/ptr" -) - -// getDefaultPlugins returns the default set of plugins. -func getDefaultPlugins() *v1.Plugins { - plugins := &v1.Plugins{ - MultiPoint: v1.PluginSet{ - Enabled: []v1.Plugin{ - {Name: names.SchedulingGates}, - {Name: names.PrioritySort}, - {Name: names.NodeUnschedulable}, - {Name: names.NodeName}, - {Name: names.TaintToleration, Weight: ptr.To[int32](3)}, - {Name: names.NodeAffinity, Weight: ptr.To[int32](2)}, - {Name: names.NodePorts}, - {Name: names.NodeResourcesFit, Weight: ptr.To[int32](1)}, - {Name: names.VolumeRestrictions}, - {Name: names.NodeVolumeLimits}, - {Name: names.VolumeBinding}, - {Name: names.VolumeZone}, - {Name: names.PodTopologySpread, Weight: ptr.To[int32](2)}, - {Name: names.InterPodAffinity, Weight: ptr.To[int32](2)}, - {Name: names.DefaultPreemption}, - {Name: names.NodeResourcesBalancedAllocation, Weight: ptr.To[int32](1)}, - {Name: names.ImageLocality, Weight: ptr.To[int32](1)}, - {Name: names.DefaultBinder}, - }, - }, - } - applyFeatureGates(plugins) - - return plugins -} - -func applyFeatureGates(config *v1.Plugins) { - if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - // This plugin should come before DefaultPreemption because if - // there is a problem with a Pod and PostFilter gets called to - // resolve the problem, it is better to first deallocate an - // idle ResourceClaim than it is to evict some Pod that might - // be doing useful work. - for i := range config.MultiPoint.Enabled { - if config.MultiPoint.Enabled[i].Name == names.DefaultPreemption { - extended := make([]v1.Plugin, 0, len(config.MultiPoint.Enabled)+1) - extended = append(extended, config.MultiPoint.Enabled[:i]...) - extended = append(extended, v1.Plugin{Name: names.DynamicResources}) - extended = append(extended, config.MultiPoint.Enabled[i:]...) - config.MultiPoint.Enabled = extended - break - } - } - } -} - -// mergePlugins merges the custom set into the given default one, handling disabled sets. -func mergePlugins(logger klog.Logger, defaultPlugins, customPlugins *v1.Plugins) *v1.Plugins { - if customPlugins == nil { - return defaultPlugins - } - - defaultPlugins.MultiPoint = mergePluginSet(logger, defaultPlugins.MultiPoint, customPlugins.MultiPoint) - defaultPlugins.PreEnqueue = mergePluginSet(logger, defaultPlugins.PreEnqueue, customPlugins.PreEnqueue) - defaultPlugins.QueueSort = mergePluginSet(logger, defaultPlugins.QueueSort, customPlugins.QueueSort) - defaultPlugins.PreFilter = mergePluginSet(logger, defaultPlugins.PreFilter, customPlugins.PreFilter) - defaultPlugins.Filter = mergePluginSet(logger, defaultPlugins.Filter, customPlugins.Filter) - defaultPlugins.PostFilter = mergePluginSet(logger, defaultPlugins.PostFilter, customPlugins.PostFilter) - defaultPlugins.PreScore = mergePluginSet(logger, defaultPlugins.PreScore, customPlugins.PreScore) - defaultPlugins.Score = mergePluginSet(logger, defaultPlugins.Score, customPlugins.Score) - defaultPlugins.Reserve = mergePluginSet(logger, defaultPlugins.Reserve, customPlugins.Reserve) - defaultPlugins.Permit = mergePluginSet(logger, defaultPlugins.Permit, customPlugins.Permit) - defaultPlugins.PreBind = mergePluginSet(logger, defaultPlugins.PreBind, customPlugins.PreBind) - defaultPlugins.Bind = mergePluginSet(logger, defaultPlugins.Bind, customPlugins.Bind) - defaultPlugins.PostBind = mergePluginSet(logger, defaultPlugins.PostBind, customPlugins.PostBind) - return defaultPlugins -} - -type pluginIndex struct { - index int - plugin v1.Plugin -} - -func mergePluginSet(logger klog.Logger, defaultPluginSet, customPluginSet v1.PluginSet) v1.PluginSet { - disabledPlugins := sets.New[string]() - enabledCustomPlugins := make(map[string]pluginIndex) - // replacedPluginIndex is a set of index of plugins, which have replaced the default plugins. - replacedPluginIndex := sets.New[int]() - var disabled []v1.Plugin - for _, disabledPlugin := range customPluginSet.Disabled { - // if the user is manually disabling any (or all, with "*") default plugins for an extension point, - // we need to track that so that the MultiPoint extension logic in the framework can know to skip - // inserting unspecified default plugins to this point. - disabled = append(disabled, v1.Plugin{Name: disabledPlugin.Name}) - disabledPlugins.Insert(disabledPlugin.Name) - } - - // With MultiPoint, we may now have some disabledPlugins in the default registry - // For example, we enable PluginX with Filter+Score through MultiPoint but disable its Score plugin by default. - for _, disabledPlugin := range defaultPluginSet.Disabled { - disabled = append(disabled, v1.Plugin{Name: disabledPlugin.Name}) - disabledPlugins.Insert(disabledPlugin.Name) - } - - for index, enabledPlugin := range customPluginSet.Enabled { - enabledCustomPlugins[enabledPlugin.Name] = pluginIndex{index, enabledPlugin} - } - var enabledPlugins []v1.Plugin - if !disabledPlugins.Has("*") { - for _, defaultEnabledPlugin := range defaultPluginSet.Enabled { - if disabledPlugins.Has(defaultEnabledPlugin.Name) { - continue - } - // The default plugin is explicitly re-configured, update the default plugin accordingly. - if customPlugin, ok := enabledCustomPlugins[defaultEnabledPlugin.Name]; ok { - logger.Info("Default plugin is explicitly re-configured; overriding", "plugin", defaultEnabledPlugin.Name) - // Update the default plugin in place to preserve order. - defaultEnabledPlugin = customPlugin.plugin - replacedPluginIndex.Insert(customPlugin.index) - } - enabledPlugins = append(enabledPlugins, defaultEnabledPlugin) - } - } - - // Append all the custom plugins which haven't replaced any default plugins. - // Note: duplicated custom plugins will still be appended here. - // If so, the instantiation of scheduler framework will detect it and abort. - for index, plugin := range customPluginSet.Enabled { - if !replacedPluginIndex.Has(index) { - enabledPlugins = append(enabledPlugins, plugin) - } - } - return v1.PluginSet{Enabled: enabledPlugins, Disabled: disabled} -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go deleted file mode 100644 index 1310ea47a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/defaults.go +++ /dev/null @@ -1,244 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1 - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apiserver/pkg/util/feature" - componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1" - "k8s.io/klog/v2" - configv1 "k8s.io/kube-scheduler/config/v1" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/utils/ptr" -) - -var defaultResourceSpec = []configv1.ResourceSpec{ - {Name: string(v1.ResourceCPU), Weight: 1}, - {Name: string(v1.ResourceMemory), Weight: 1}, -} - -func addDefaultingFuncs(scheme *runtime.Scheme) error { - return RegisterDefaults(scheme) -} - -func pluginsNames(p *configv1.Plugins) []string { - if p == nil { - return nil - } - extensions := []configv1.PluginSet{ - p.MultiPoint, - p.PreFilter, - p.Filter, - p.PostFilter, - p.Reserve, - p.PreScore, - p.Score, - p.PreBind, - p.Bind, - p.PostBind, - p.Permit, - p.PreEnqueue, - p.QueueSort, - } - n := sets.New[string]() - for _, e := range extensions { - for _, pg := range e.Enabled { - n.Insert(pg.Name) - } - } - return sets.List(n) -} - -func setDefaults_KubeSchedulerProfile(logger klog.Logger, prof *configv1.KubeSchedulerProfile) { - // Set default plugins. - prof.Plugins = mergePlugins(logger, getDefaultPlugins(), prof.Plugins) - // Set default plugin configs. - scheme := GetPluginArgConversionScheme() - existingConfigs := sets.New[string]() - for j := range prof.PluginConfig { - existingConfigs.Insert(prof.PluginConfig[j].Name) - args := prof.PluginConfig[j].Args.Object - if _, isUnknown := args.(*runtime.Unknown); isUnknown { - continue - } - scheme.Default(args) - } - - // Append default configs for plugins that didn't have one explicitly set. - for _, name := range pluginsNames(prof.Plugins) { - if existingConfigs.Has(name) { - continue - } - gvk := configv1.SchemeGroupVersion.WithKind(name + "Args") - args, err := scheme.New(gvk) - if err != nil { - // This plugin is out-of-tree or doesn't require configuration. - continue - } - scheme.Default(args) - args.GetObjectKind().SetGroupVersionKind(gvk) - prof.PluginConfig = append(prof.PluginConfig, configv1.PluginConfig{ - Name: name, - Args: runtime.RawExtension{Object: args}, - }) - } -} - -// SetDefaults_KubeSchedulerConfiguration sets additional defaults -func SetDefaults_KubeSchedulerConfiguration(obj *configv1.KubeSchedulerConfiguration) { - logger := klog.TODO() // called by generated code that doesn't pass a logger. See #115724 - if obj.Parallelism == nil { - obj.Parallelism = ptr.To[int32](16) - } - - if len(obj.Profiles) == 0 { - obj.Profiles = append(obj.Profiles, configv1.KubeSchedulerProfile{}) - } - // Only apply a default scheduler name when there is a single profile. - // Validation will ensure that every profile has a non-empty unique name. - if len(obj.Profiles) == 1 && obj.Profiles[0].SchedulerName == nil { - obj.Profiles[0].SchedulerName = ptr.To(v1.DefaultSchedulerName) - } - - // Add the default set of plugins and apply the configuration. - for i := range obj.Profiles { - prof := &obj.Profiles[i] - setDefaults_KubeSchedulerProfile(logger, prof) - } - - if obj.PercentageOfNodesToScore == nil { - obj.PercentageOfNodesToScore = ptr.To[int32](config.DefaultPercentageOfNodesToScore) - } - - if len(obj.LeaderElection.ResourceLock) == 0 { - // Use lease-based leader election to reduce cost. - // We migrated for EndpointsLease lock in 1.17 and starting in 1.20 we - // migrated to Lease lock. - obj.LeaderElection.ResourceLock = "leases" - } - if len(obj.LeaderElection.ResourceNamespace) == 0 { - obj.LeaderElection.ResourceNamespace = configv1.SchedulerDefaultLockObjectNamespace - } - if len(obj.LeaderElection.ResourceName) == 0 { - obj.LeaderElection.ResourceName = configv1.SchedulerDefaultLockObjectName - } - - if len(obj.ClientConnection.ContentType) == 0 { - obj.ClientConnection.ContentType = "application/vnd.kubernetes.protobuf" - } - // Scheduler has an opinion about QPS/Burst, setting specific defaults for itself, instead of generic settings. - if obj.ClientConnection.QPS == 0.0 { - obj.ClientConnection.QPS = 50.0 - } - if obj.ClientConnection.Burst == 0 { - obj.ClientConnection.Burst = 100 - } - - // Use the default LeaderElectionConfiguration options - componentbaseconfigv1alpha1.RecommendedDefaultLeaderElectionConfiguration(&obj.LeaderElection) - - if obj.PodInitialBackoffSeconds == nil { - obj.PodInitialBackoffSeconds = ptr.To[int64](1) - } - - if obj.PodMaxBackoffSeconds == nil { - obj.PodMaxBackoffSeconds = ptr.To[int64](10) - } - - // Enable profiling by default in the scheduler - if obj.EnableProfiling == nil { - obj.EnableProfiling = ptr.To(true) - } - - // Enable contention profiling by default if profiling is enabled - if *obj.EnableProfiling && obj.EnableContentionProfiling == nil { - obj.EnableContentionProfiling = ptr.To(true) - } -} - -func SetDefaults_DefaultPreemptionArgs(obj *configv1.DefaultPreemptionArgs) { - if obj.MinCandidateNodesPercentage == nil { - obj.MinCandidateNodesPercentage = ptr.To[int32](10) - } - if obj.MinCandidateNodesAbsolute == nil { - obj.MinCandidateNodesAbsolute = ptr.To[int32](100) - } -} - -func SetDefaults_InterPodAffinityArgs(obj *configv1.InterPodAffinityArgs) { - if obj.HardPodAffinityWeight == nil { - obj.HardPodAffinityWeight = ptr.To[int32](1) - } -} - -func SetDefaults_VolumeBindingArgs(obj *configv1.VolumeBindingArgs) { - if obj.BindTimeoutSeconds == nil { - obj.BindTimeoutSeconds = ptr.To[int64](600) - } - if len(obj.Shape) == 0 && feature.DefaultFeatureGate.Enabled(features.StorageCapacityScoring) { - obj.Shape = []configv1.UtilizationShapePoint{ - { - Utilization: 0, - Score: int32(config.MaxCustomPriorityScore), - }, - { - Utilization: 100, - Score: 0, - }, - } - } -} - -func SetDefaults_NodeResourcesBalancedAllocationArgs(obj *configv1.NodeResourcesBalancedAllocationArgs) { - if len(obj.Resources) == 0 { - obj.Resources = defaultResourceSpec - return - } - // If the weight is not set or it is explicitly set to 0, then apply the default weight(1) instead. - for i := range obj.Resources { - if obj.Resources[i].Weight == 0 { - obj.Resources[i].Weight = 1 - } - } -} - -func SetDefaults_PodTopologySpreadArgs(obj *configv1.PodTopologySpreadArgs) { - if obj.DefaultingType == "" { - obj.DefaultingType = configv1.SystemDefaulting - } -} - -func SetDefaults_NodeResourcesFitArgs(obj *configv1.NodeResourcesFitArgs) { - if obj.ScoringStrategy == nil { - obj.ScoringStrategy = &configv1.ScoringStrategy{ - Type: configv1.ScoringStrategyType(config.LeastAllocated), - Resources: defaultResourceSpec, - } - } - if len(obj.ScoringStrategy.Resources) == 0 { - // If no resources specified, use the default set. - obj.ScoringStrategy.Resources = append(obj.ScoringStrategy.Resources, defaultResourceSpec...) - } - for i := range obj.ScoringStrategy.Resources { - if obj.ScoringStrategy.Resources[i].Weight == 0 { - obj.ScoringStrategy.Resources[i].Weight = 1 - } - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/doc.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/doc.go deleted file mode 100644 index 4e2ff4456..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/doc.go +++ /dev/null @@ -1,24 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// +k8s:deepcopy-gen=package -// +k8s:conversion-gen=k8s.io/kubernetes/pkg/scheduler/apis/config -// +k8s:conversion-gen-external-types=k8s.io/kube-scheduler/config/v1 -// +k8s:defaulter-gen=TypeMeta -// +k8s:defaulter-gen-input=k8s.io/kube-scheduler/config/v1 -// +groupName=kubescheduler.config.k8s.io - -package v1 diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/register.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/register.go deleted file mode 100644 index 9a32736c8..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/register.go +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package v1 - -import ( - v1 "k8s.io/kube-scheduler/config/v1" -) - -// GroupName is the group name used in this package -const GroupName = v1.GroupName - -// SchemeGroupVersion is group version used to register these objects -var SchemeGroupVersion = v1.SchemeGroupVersion - -var ( - // localSchemeBuilder extends the SchemeBuilder instance with the external types. In this package, - // defaulting and conversion init funcs are registered as well. - localSchemeBuilder = &v1.SchemeBuilder - // AddToScheme is a global function that registers this API group & version to a scheme - AddToScheme = localSchemeBuilder.AddToScheme -) - -func init() { - // We only register manually written functions here. The registration of the - // generated functions takes place in the generated files. The separation - // makes the code compile even when the generated files are missing. - localSchemeBuilder.Register(addDefaultingFuncs) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go deleted file mode 100644 index ab8518c88..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.conversion.go +++ /dev/null @@ -1,946 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by conversion-gen. DO NOT EDIT. - -package v1 - -import ( - unsafe "unsafe" - - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - conversion "k8s.io/apimachinery/pkg/conversion" - runtime "k8s.io/apimachinery/pkg/runtime" - v1alpha1 "k8s.io/component-base/config/v1alpha1" - configv1 "k8s.io/kube-scheduler/config/v1" - config "k8s.io/kubernetes/pkg/scheduler/apis/config" -) - -func init() { - localSchemeBuilder.Register(RegisterConversions) -} - -// RegisterConversions adds conversion functions to the given scheme. -// Public to allow building arbitrary schemes. -func RegisterConversions(s *runtime.Scheme) error { - if err := s.AddGeneratedConversionFunc((*configv1.DefaultPreemptionArgs)(nil), (*config.DefaultPreemptionArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_DefaultPreemptionArgs_To_config_DefaultPreemptionArgs(a.(*configv1.DefaultPreemptionArgs), b.(*config.DefaultPreemptionArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.DefaultPreemptionArgs)(nil), (*configv1.DefaultPreemptionArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_DefaultPreemptionArgs_To_v1_DefaultPreemptionArgs(a.(*config.DefaultPreemptionArgs), b.(*configv1.DefaultPreemptionArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.Extender)(nil), (*config.Extender)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_Extender_To_config_Extender(a.(*configv1.Extender), b.(*config.Extender), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.Extender)(nil), (*configv1.Extender)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_Extender_To_v1_Extender(a.(*config.Extender), b.(*configv1.Extender), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.ExtenderManagedResource)(nil), (*config.ExtenderManagedResource)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource(a.(*configv1.ExtenderManagedResource), b.(*config.ExtenderManagedResource), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.ExtenderManagedResource)(nil), (*configv1.ExtenderManagedResource)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_ExtenderManagedResource_To_v1_ExtenderManagedResource(a.(*config.ExtenderManagedResource), b.(*configv1.ExtenderManagedResource), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.ExtenderTLSConfig)(nil), (*config.ExtenderTLSConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ExtenderTLSConfig_To_config_ExtenderTLSConfig(a.(*configv1.ExtenderTLSConfig), b.(*config.ExtenderTLSConfig), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.ExtenderTLSConfig)(nil), (*configv1.ExtenderTLSConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_ExtenderTLSConfig_To_v1_ExtenderTLSConfig(a.(*config.ExtenderTLSConfig), b.(*configv1.ExtenderTLSConfig), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.InterPodAffinityArgs)(nil), (*config.InterPodAffinityArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(a.(*configv1.InterPodAffinityArgs), b.(*config.InterPodAffinityArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.InterPodAffinityArgs)(nil), (*configv1.InterPodAffinityArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_InterPodAffinityArgs_To_v1_InterPodAffinityArgs(a.(*config.InterPodAffinityArgs), b.(*configv1.InterPodAffinityArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.KubeSchedulerProfile)(nil), (*config.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(a.(*configv1.KubeSchedulerProfile), b.(*config.KubeSchedulerProfile), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.KubeSchedulerProfile)(nil), (*configv1.KubeSchedulerProfile)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_KubeSchedulerProfile_To_v1_KubeSchedulerProfile(a.(*config.KubeSchedulerProfile), b.(*configv1.KubeSchedulerProfile), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.NodeAffinityArgs)(nil), (*config.NodeAffinityArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_NodeAffinityArgs_To_config_NodeAffinityArgs(a.(*configv1.NodeAffinityArgs), b.(*config.NodeAffinityArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.NodeAffinityArgs)(nil), (*configv1.NodeAffinityArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_NodeAffinityArgs_To_v1_NodeAffinityArgs(a.(*config.NodeAffinityArgs), b.(*configv1.NodeAffinityArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.NodeResourcesBalancedAllocationArgs)(nil), (*config.NodeResourcesBalancedAllocationArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_NodeResourcesBalancedAllocationArgs_To_config_NodeResourcesBalancedAllocationArgs(a.(*configv1.NodeResourcesBalancedAllocationArgs), b.(*config.NodeResourcesBalancedAllocationArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.NodeResourcesBalancedAllocationArgs)(nil), (*configv1.NodeResourcesBalancedAllocationArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_NodeResourcesBalancedAllocationArgs_To_v1_NodeResourcesBalancedAllocationArgs(a.(*config.NodeResourcesBalancedAllocationArgs), b.(*configv1.NodeResourcesBalancedAllocationArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.NodeResourcesFitArgs)(nil), (*config.NodeResourcesFitArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_NodeResourcesFitArgs_To_config_NodeResourcesFitArgs(a.(*configv1.NodeResourcesFitArgs), b.(*config.NodeResourcesFitArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.NodeResourcesFitArgs)(nil), (*configv1.NodeResourcesFitArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_NodeResourcesFitArgs_To_v1_NodeResourcesFitArgs(a.(*config.NodeResourcesFitArgs), b.(*configv1.NodeResourcesFitArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.Plugin)(nil), (*config.Plugin)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_Plugin_To_config_Plugin(a.(*configv1.Plugin), b.(*config.Plugin), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.Plugin)(nil), (*configv1.Plugin)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_Plugin_To_v1_Plugin(a.(*config.Plugin), b.(*configv1.Plugin), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.PluginConfig)(nil), (*config.PluginConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_PluginConfig_To_config_PluginConfig(a.(*configv1.PluginConfig), b.(*config.PluginConfig), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.PluginConfig)(nil), (*configv1.PluginConfig)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_PluginConfig_To_v1_PluginConfig(a.(*config.PluginConfig), b.(*configv1.PluginConfig), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.PluginSet)(nil), (*config.PluginSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_PluginSet_To_config_PluginSet(a.(*configv1.PluginSet), b.(*config.PluginSet), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.PluginSet)(nil), (*configv1.PluginSet)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_PluginSet_To_v1_PluginSet(a.(*config.PluginSet), b.(*configv1.PluginSet), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.Plugins)(nil), (*config.Plugins)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_Plugins_To_config_Plugins(a.(*configv1.Plugins), b.(*config.Plugins), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.Plugins)(nil), (*configv1.Plugins)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_Plugins_To_v1_Plugins(a.(*config.Plugins), b.(*configv1.Plugins), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.PodTopologySpreadArgs)(nil), (*config.PodTopologySpreadArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_PodTopologySpreadArgs_To_config_PodTopologySpreadArgs(a.(*configv1.PodTopologySpreadArgs), b.(*config.PodTopologySpreadArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.PodTopologySpreadArgs)(nil), (*configv1.PodTopologySpreadArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_PodTopologySpreadArgs_To_v1_PodTopologySpreadArgs(a.(*config.PodTopologySpreadArgs), b.(*configv1.PodTopologySpreadArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.RequestedToCapacityRatioParam)(nil), (*config.RequestedToCapacityRatioParam)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_RequestedToCapacityRatioParam_To_config_RequestedToCapacityRatioParam(a.(*configv1.RequestedToCapacityRatioParam), b.(*config.RequestedToCapacityRatioParam), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.RequestedToCapacityRatioParam)(nil), (*configv1.RequestedToCapacityRatioParam)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_RequestedToCapacityRatioParam_To_v1_RequestedToCapacityRatioParam(a.(*config.RequestedToCapacityRatioParam), b.(*configv1.RequestedToCapacityRatioParam), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.ResourceSpec)(nil), (*config.ResourceSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ResourceSpec_To_config_ResourceSpec(a.(*configv1.ResourceSpec), b.(*config.ResourceSpec), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.ResourceSpec)(nil), (*configv1.ResourceSpec)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_ResourceSpec_To_v1_ResourceSpec(a.(*config.ResourceSpec), b.(*configv1.ResourceSpec), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.ScoringStrategy)(nil), (*config.ScoringStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_ScoringStrategy_To_config_ScoringStrategy(a.(*configv1.ScoringStrategy), b.(*config.ScoringStrategy), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.ScoringStrategy)(nil), (*configv1.ScoringStrategy)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_ScoringStrategy_To_v1_ScoringStrategy(a.(*config.ScoringStrategy), b.(*configv1.ScoringStrategy), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.UtilizationShapePoint)(nil), (*config.UtilizationShapePoint)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_UtilizationShapePoint_To_config_UtilizationShapePoint(a.(*configv1.UtilizationShapePoint), b.(*config.UtilizationShapePoint), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.UtilizationShapePoint)(nil), (*configv1.UtilizationShapePoint)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_UtilizationShapePoint_To_v1_UtilizationShapePoint(a.(*config.UtilizationShapePoint), b.(*configv1.UtilizationShapePoint), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*configv1.VolumeBindingArgs)(nil), (*config.VolumeBindingArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_VolumeBindingArgs_To_config_VolumeBindingArgs(a.(*configv1.VolumeBindingArgs), b.(*config.VolumeBindingArgs), scope) - }); err != nil { - return err - } - if err := s.AddGeneratedConversionFunc((*config.VolumeBindingArgs)(nil), (*configv1.VolumeBindingArgs)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_VolumeBindingArgs_To_v1_VolumeBindingArgs(a.(*config.VolumeBindingArgs), b.(*configv1.VolumeBindingArgs), scope) - }); err != nil { - return err - } - if err := s.AddConversionFunc((*config.KubeSchedulerConfiguration)(nil), (*configv1.KubeSchedulerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_config_KubeSchedulerConfiguration_To_v1_KubeSchedulerConfiguration(a.(*config.KubeSchedulerConfiguration), b.(*configv1.KubeSchedulerConfiguration), scope) - }); err != nil { - return err - } - if err := s.AddConversionFunc((*configv1.KubeSchedulerConfiguration)(nil), (*config.KubeSchedulerConfiguration)(nil), func(a, b interface{}, scope conversion.Scope) error { - return Convert_v1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(a.(*configv1.KubeSchedulerConfiguration), b.(*config.KubeSchedulerConfiguration), scope) - }); err != nil { - return err - } - return nil -} - -func autoConvert_v1_DefaultPreemptionArgs_To_config_DefaultPreemptionArgs(in *configv1.DefaultPreemptionArgs, out *config.DefaultPreemptionArgs, s conversion.Scope) error { - if err := metav1.Convert_Pointer_int32_To_int32(&in.MinCandidateNodesPercentage, &out.MinCandidateNodesPercentage, s); err != nil { - return err - } - if err := metav1.Convert_Pointer_int32_To_int32(&in.MinCandidateNodesAbsolute, &out.MinCandidateNodesAbsolute, s); err != nil { - return err - } - return nil -} - -// Convert_v1_DefaultPreemptionArgs_To_config_DefaultPreemptionArgs is an autogenerated conversion function. -func Convert_v1_DefaultPreemptionArgs_To_config_DefaultPreemptionArgs(in *configv1.DefaultPreemptionArgs, out *config.DefaultPreemptionArgs, s conversion.Scope) error { - return autoConvert_v1_DefaultPreemptionArgs_To_config_DefaultPreemptionArgs(in, out, s) -} - -func autoConvert_config_DefaultPreemptionArgs_To_v1_DefaultPreemptionArgs(in *config.DefaultPreemptionArgs, out *configv1.DefaultPreemptionArgs, s conversion.Scope) error { - if err := metav1.Convert_int32_To_Pointer_int32(&in.MinCandidateNodesPercentage, &out.MinCandidateNodesPercentage, s); err != nil { - return err - } - if err := metav1.Convert_int32_To_Pointer_int32(&in.MinCandidateNodesAbsolute, &out.MinCandidateNodesAbsolute, s); err != nil { - return err - } - return nil -} - -// Convert_config_DefaultPreemptionArgs_To_v1_DefaultPreemptionArgs is an autogenerated conversion function. -func Convert_config_DefaultPreemptionArgs_To_v1_DefaultPreemptionArgs(in *config.DefaultPreemptionArgs, out *configv1.DefaultPreemptionArgs, s conversion.Scope) error { - return autoConvert_config_DefaultPreemptionArgs_To_v1_DefaultPreemptionArgs(in, out, s) -} - -func autoConvert_v1_Extender_To_config_Extender(in *configv1.Extender, out *config.Extender, s conversion.Scope) error { - out.URLPrefix = in.URLPrefix - out.FilterVerb = in.FilterVerb - out.PreemptVerb = in.PreemptVerb - out.PrioritizeVerb = in.PrioritizeVerb - out.Weight = in.Weight - out.BindVerb = in.BindVerb - out.EnableHTTPS = in.EnableHTTPS - out.TLSConfig = (*config.ExtenderTLSConfig)(unsafe.Pointer(in.TLSConfig)) - out.HTTPTimeout = in.HTTPTimeout - out.NodeCacheCapable = in.NodeCacheCapable - out.ManagedResources = *(*[]config.ExtenderManagedResource)(unsafe.Pointer(&in.ManagedResources)) - out.Ignorable = in.Ignorable - return nil -} - -// Convert_v1_Extender_To_config_Extender is an autogenerated conversion function. -func Convert_v1_Extender_To_config_Extender(in *configv1.Extender, out *config.Extender, s conversion.Scope) error { - return autoConvert_v1_Extender_To_config_Extender(in, out, s) -} - -func autoConvert_config_Extender_To_v1_Extender(in *config.Extender, out *configv1.Extender, s conversion.Scope) error { - out.URLPrefix = in.URLPrefix - out.FilterVerb = in.FilterVerb - out.PreemptVerb = in.PreemptVerb - out.PrioritizeVerb = in.PrioritizeVerb - out.Weight = in.Weight - out.BindVerb = in.BindVerb - out.EnableHTTPS = in.EnableHTTPS - out.TLSConfig = (*configv1.ExtenderTLSConfig)(unsafe.Pointer(in.TLSConfig)) - out.HTTPTimeout = in.HTTPTimeout - out.NodeCacheCapable = in.NodeCacheCapable - out.ManagedResources = *(*[]configv1.ExtenderManagedResource)(unsafe.Pointer(&in.ManagedResources)) - out.Ignorable = in.Ignorable - return nil -} - -// Convert_config_Extender_To_v1_Extender is an autogenerated conversion function. -func Convert_config_Extender_To_v1_Extender(in *config.Extender, out *configv1.Extender, s conversion.Scope) error { - return autoConvert_config_Extender_To_v1_Extender(in, out, s) -} - -func autoConvert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource(in *configv1.ExtenderManagedResource, out *config.ExtenderManagedResource, s conversion.Scope) error { - out.Name = in.Name - out.IgnoredByScheduler = in.IgnoredByScheduler - return nil -} - -// Convert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource is an autogenerated conversion function. -func Convert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource(in *configv1.ExtenderManagedResource, out *config.ExtenderManagedResource, s conversion.Scope) error { - return autoConvert_v1_ExtenderManagedResource_To_config_ExtenderManagedResource(in, out, s) -} - -func autoConvert_config_ExtenderManagedResource_To_v1_ExtenderManagedResource(in *config.ExtenderManagedResource, out *configv1.ExtenderManagedResource, s conversion.Scope) error { - out.Name = in.Name - out.IgnoredByScheduler = in.IgnoredByScheduler - return nil -} - -// Convert_config_ExtenderManagedResource_To_v1_ExtenderManagedResource is an autogenerated conversion function. -func Convert_config_ExtenderManagedResource_To_v1_ExtenderManagedResource(in *config.ExtenderManagedResource, out *configv1.ExtenderManagedResource, s conversion.Scope) error { - return autoConvert_config_ExtenderManagedResource_To_v1_ExtenderManagedResource(in, out, s) -} - -func autoConvert_v1_ExtenderTLSConfig_To_config_ExtenderTLSConfig(in *configv1.ExtenderTLSConfig, out *config.ExtenderTLSConfig, s conversion.Scope) error { - out.Insecure = in.Insecure - out.ServerName = in.ServerName - out.CertFile = in.CertFile - out.KeyFile = in.KeyFile - out.CAFile = in.CAFile - out.CertData = *(*[]byte)(unsafe.Pointer(&in.CertData)) - out.KeyData = *(*[]byte)(unsafe.Pointer(&in.KeyData)) - out.CAData = *(*[]byte)(unsafe.Pointer(&in.CAData)) - return nil -} - -// Convert_v1_ExtenderTLSConfig_To_config_ExtenderTLSConfig is an autogenerated conversion function. -func Convert_v1_ExtenderTLSConfig_To_config_ExtenderTLSConfig(in *configv1.ExtenderTLSConfig, out *config.ExtenderTLSConfig, s conversion.Scope) error { - return autoConvert_v1_ExtenderTLSConfig_To_config_ExtenderTLSConfig(in, out, s) -} - -func autoConvert_config_ExtenderTLSConfig_To_v1_ExtenderTLSConfig(in *config.ExtenderTLSConfig, out *configv1.ExtenderTLSConfig, s conversion.Scope) error { - out.Insecure = in.Insecure - out.ServerName = in.ServerName - out.CertFile = in.CertFile - out.KeyFile = in.KeyFile - out.CAFile = in.CAFile - out.CertData = *(*[]byte)(unsafe.Pointer(&in.CertData)) - out.KeyData = *(*[]byte)(unsafe.Pointer(&in.KeyData)) - out.CAData = *(*[]byte)(unsafe.Pointer(&in.CAData)) - return nil -} - -// Convert_config_ExtenderTLSConfig_To_v1_ExtenderTLSConfig is an autogenerated conversion function. -func Convert_config_ExtenderTLSConfig_To_v1_ExtenderTLSConfig(in *config.ExtenderTLSConfig, out *configv1.ExtenderTLSConfig, s conversion.Scope) error { - return autoConvert_config_ExtenderTLSConfig_To_v1_ExtenderTLSConfig(in, out, s) -} - -func autoConvert_v1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in *configv1.InterPodAffinityArgs, out *config.InterPodAffinityArgs, s conversion.Scope) error { - if err := metav1.Convert_Pointer_int32_To_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil { - return err - } - out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods - return nil -} - -// Convert_v1_InterPodAffinityArgs_To_config_InterPodAffinityArgs is an autogenerated conversion function. -func Convert_v1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in *configv1.InterPodAffinityArgs, out *config.InterPodAffinityArgs, s conversion.Scope) error { - return autoConvert_v1_InterPodAffinityArgs_To_config_InterPodAffinityArgs(in, out, s) -} - -func autoConvert_config_InterPodAffinityArgs_To_v1_InterPodAffinityArgs(in *config.InterPodAffinityArgs, out *configv1.InterPodAffinityArgs, s conversion.Scope) error { - if err := metav1.Convert_int32_To_Pointer_int32(&in.HardPodAffinityWeight, &out.HardPodAffinityWeight, s); err != nil { - return err - } - out.IgnorePreferredTermsOfExistingPods = in.IgnorePreferredTermsOfExistingPods - return nil -} - -// Convert_config_InterPodAffinityArgs_To_v1_InterPodAffinityArgs is an autogenerated conversion function. -func Convert_config_InterPodAffinityArgs_To_v1_InterPodAffinityArgs(in *config.InterPodAffinityArgs, out *configv1.InterPodAffinityArgs, s conversion.Scope) error { - return autoConvert_config_InterPodAffinityArgs_To_v1_InterPodAffinityArgs(in, out, s) -} - -func autoConvert_v1_KubeSchedulerConfiguration_To_config_KubeSchedulerConfiguration(in *configv1.KubeSchedulerConfiguration, out *config.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := metav1.Convert_Pointer_int32_To_int32(&in.Parallelism, &out.Parallelism, s); err != nil { - return err - } - if err := v1alpha1.Convert_v1alpha1_LeaderElectionConfiguration_To_config_LeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil { - return err - } - if err := v1alpha1.Convert_v1alpha1_ClientConnectionConfiguration_To_config_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { - return err - } - if err := v1alpha1.Convert_v1alpha1_DebuggingConfiguration_To_config_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil { - return err - } - out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore)) - if err := metav1.Convert_Pointer_int64_To_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil { - return err - } - if err := metav1.Convert_Pointer_int64_To_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { - return err - } - if in.Profiles != nil { - in, out := &in.Profiles, &out.Profiles - *out = make([]config.KubeSchedulerProfile, len(*in)) - for i := range *in { - if err := Convert_v1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.Profiles = nil - } - out.Extenders = *(*[]config.Extender)(unsafe.Pointer(&in.Extenders)) - out.DelayCacheUntilActive = in.DelayCacheUntilActive - return nil -} - -func autoConvert_config_KubeSchedulerConfiguration_To_v1_KubeSchedulerConfiguration(in *config.KubeSchedulerConfiguration, out *configv1.KubeSchedulerConfiguration, s conversion.Scope) error { - if err := metav1.Convert_int32_To_Pointer_int32(&in.Parallelism, &out.Parallelism, s); err != nil { - return err - } - if err := v1alpha1.Convert_config_LeaderElectionConfiguration_To_v1alpha1_LeaderElectionConfiguration(&in.LeaderElection, &out.LeaderElection, s); err != nil { - return err - } - if err := v1alpha1.Convert_config_ClientConnectionConfiguration_To_v1alpha1_ClientConnectionConfiguration(&in.ClientConnection, &out.ClientConnection, s); err != nil { - return err - } - if err := v1alpha1.Convert_config_DebuggingConfiguration_To_v1alpha1_DebuggingConfiguration(&in.DebuggingConfiguration, &out.DebuggingConfiguration, s); err != nil { - return err - } - out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore)) - if err := metav1.Convert_int64_To_Pointer_int64(&in.PodInitialBackoffSeconds, &out.PodInitialBackoffSeconds, s); err != nil { - return err - } - if err := metav1.Convert_int64_To_Pointer_int64(&in.PodMaxBackoffSeconds, &out.PodMaxBackoffSeconds, s); err != nil { - return err - } - if in.Profiles != nil { - in, out := &in.Profiles, &out.Profiles - *out = make([]configv1.KubeSchedulerProfile, len(*in)) - for i := range *in { - if err := Convert_config_KubeSchedulerProfile_To_v1_KubeSchedulerProfile(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.Profiles = nil - } - out.Extenders = *(*[]configv1.Extender)(unsafe.Pointer(&in.Extenders)) - out.DelayCacheUntilActive = in.DelayCacheUntilActive - return nil -} - -func autoConvert_v1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in *configv1.KubeSchedulerProfile, out *config.KubeSchedulerProfile, s conversion.Scope) error { - if err := metav1.Convert_Pointer_string_To_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { - return err - } - out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore)) - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(config.Plugins) - if err := Convert_v1_Plugins_To_config_Plugins(*in, *out, s); err != nil { - return err - } - } else { - out.Plugins = nil - } - if in.PluginConfig != nil { - in, out := &in.PluginConfig, &out.PluginConfig - *out = make([]config.PluginConfig, len(*in)) - for i := range *in { - if err := Convert_v1_PluginConfig_To_config_PluginConfig(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.PluginConfig = nil - } - return nil -} - -// Convert_v1_KubeSchedulerProfile_To_config_KubeSchedulerProfile is an autogenerated conversion function. -func Convert_v1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in *configv1.KubeSchedulerProfile, out *config.KubeSchedulerProfile, s conversion.Scope) error { - return autoConvert_v1_KubeSchedulerProfile_To_config_KubeSchedulerProfile(in, out, s) -} - -func autoConvert_config_KubeSchedulerProfile_To_v1_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *configv1.KubeSchedulerProfile, s conversion.Scope) error { - if err := metav1.Convert_string_To_Pointer_string(&in.SchedulerName, &out.SchedulerName, s); err != nil { - return err - } - out.PercentageOfNodesToScore = (*int32)(unsafe.Pointer(in.PercentageOfNodesToScore)) - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(configv1.Plugins) - if err := Convert_config_Plugins_To_v1_Plugins(*in, *out, s); err != nil { - return err - } - } else { - out.Plugins = nil - } - if in.PluginConfig != nil { - in, out := &in.PluginConfig, &out.PluginConfig - *out = make([]configv1.PluginConfig, len(*in)) - for i := range *in { - if err := Convert_config_PluginConfig_To_v1_PluginConfig(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.PluginConfig = nil - } - return nil -} - -// Convert_config_KubeSchedulerProfile_To_v1_KubeSchedulerProfile is an autogenerated conversion function. -func Convert_config_KubeSchedulerProfile_To_v1_KubeSchedulerProfile(in *config.KubeSchedulerProfile, out *configv1.KubeSchedulerProfile, s conversion.Scope) error { - return autoConvert_config_KubeSchedulerProfile_To_v1_KubeSchedulerProfile(in, out, s) -} - -func autoConvert_v1_NodeAffinityArgs_To_config_NodeAffinityArgs(in *configv1.NodeAffinityArgs, out *config.NodeAffinityArgs, s conversion.Scope) error { - out.AddedAffinity = (*corev1.NodeAffinity)(unsafe.Pointer(in.AddedAffinity)) - return nil -} - -// Convert_v1_NodeAffinityArgs_To_config_NodeAffinityArgs is an autogenerated conversion function. -func Convert_v1_NodeAffinityArgs_To_config_NodeAffinityArgs(in *configv1.NodeAffinityArgs, out *config.NodeAffinityArgs, s conversion.Scope) error { - return autoConvert_v1_NodeAffinityArgs_To_config_NodeAffinityArgs(in, out, s) -} - -func autoConvert_config_NodeAffinityArgs_To_v1_NodeAffinityArgs(in *config.NodeAffinityArgs, out *configv1.NodeAffinityArgs, s conversion.Scope) error { - out.AddedAffinity = (*corev1.NodeAffinity)(unsafe.Pointer(in.AddedAffinity)) - return nil -} - -// Convert_config_NodeAffinityArgs_To_v1_NodeAffinityArgs is an autogenerated conversion function. -func Convert_config_NodeAffinityArgs_To_v1_NodeAffinityArgs(in *config.NodeAffinityArgs, out *configv1.NodeAffinityArgs, s conversion.Scope) error { - return autoConvert_config_NodeAffinityArgs_To_v1_NodeAffinityArgs(in, out, s) -} - -func autoConvert_v1_NodeResourcesBalancedAllocationArgs_To_config_NodeResourcesBalancedAllocationArgs(in *configv1.NodeResourcesBalancedAllocationArgs, out *config.NodeResourcesBalancedAllocationArgs, s conversion.Scope) error { - out.Resources = *(*[]config.ResourceSpec)(unsafe.Pointer(&in.Resources)) - return nil -} - -// Convert_v1_NodeResourcesBalancedAllocationArgs_To_config_NodeResourcesBalancedAllocationArgs is an autogenerated conversion function. -func Convert_v1_NodeResourcesBalancedAllocationArgs_To_config_NodeResourcesBalancedAllocationArgs(in *configv1.NodeResourcesBalancedAllocationArgs, out *config.NodeResourcesBalancedAllocationArgs, s conversion.Scope) error { - return autoConvert_v1_NodeResourcesBalancedAllocationArgs_To_config_NodeResourcesBalancedAllocationArgs(in, out, s) -} - -func autoConvert_config_NodeResourcesBalancedAllocationArgs_To_v1_NodeResourcesBalancedAllocationArgs(in *config.NodeResourcesBalancedAllocationArgs, out *configv1.NodeResourcesBalancedAllocationArgs, s conversion.Scope) error { - out.Resources = *(*[]configv1.ResourceSpec)(unsafe.Pointer(&in.Resources)) - return nil -} - -// Convert_config_NodeResourcesBalancedAllocationArgs_To_v1_NodeResourcesBalancedAllocationArgs is an autogenerated conversion function. -func Convert_config_NodeResourcesBalancedAllocationArgs_To_v1_NodeResourcesBalancedAllocationArgs(in *config.NodeResourcesBalancedAllocationArgs, out *configv1.NodeResourcesBalancedAllocationArgs, s conversion.Scope) error { - return autoConvert_config_NodeResourcesBalancedAllocationArgs_To_v1_NodeResourcesBalancedAllocationArgs(in, out, s) -} - -func autoConvert_v1_NodeResourcesFitArgs_To_config_NodeResourcesFitArgs(in *configv1.NodeResourcesFitArgs, out *config.NodeResourcesFitArgs, s conversion.Scope) error { - out.IgnoredResources = *(*[]string)(unsafe.Pointer(&in.IgnoredResources)) - out.IgnoredResourceGroups = *(*[]string)(unsafe.Pointer(&in.IgnoredResourceGroups)) - out.ScoringStrategy = (*config.ScoringStrategy)(unsafe.Pointer(in.ScoringStrategy)) - return nil -} - -// Convert_v1_NodeResourcesFitArgs_To_config_NodeResourcesFitArgs is an autogenerated conversion function. -func Convert_v1_NodeResourcesFitArgs_To_config_NodeResourcesFitArgs(in *configv1.NodeResourcesFitArgs, out *config.NodeResourcesFitArgs, s conversion.Scope) error { - return autoConvert_v1_NodeResourcesFitArgs_To_config_NodeResourcesFitArgs(in, out, s) -} - -func autoConvert_config_NodeResourcesFitArgs_To_v1_NodeResourcesFitArgs(in *config.NodeResourcesFitArgs, out *configv1.NodeResourcesFitArgs, s conversion.Scope) error { - out.IgnoredResources = *(*[]string)(unsafe.Pointer(&in.IgnoredResources)) - out.IgnoredResourceGroups = *(*[]string)(unsafe.Pointer(&in.IgnoredResourceGroups)) - out.ScoringStrategy = (*configv1.ScoringStrategy)(unsafe.Pointer(in.ScoringStrategy)) - return nil -} - -// Convert_config_NodeResourcesFitArgs_To_v1_NodeResourcesFitArgs is an autogenerated conversion function. -func Convert_config_NodeResourcesFitArgs_To_v1_NodeResourcesFitArgs(in *config.NodeResourcesFitArgs, out *configv1.NodeResourcesFitArgs, s conversion.Scope) error { - return autoConvert_config_NodeResourcesFitArgs_To_v1_NodeResourcesFitArgs(in, out, s) -} - -func autoConvert_v1_Plugin_To_config_Plugin(in *configv1.Plugin, out *config.Plugin, s conversion.Scope) error { - out.Name = in.Name - if err := metav1.Convert_Pointer_int32_To_int32(&in.Weight, &out.Weight, s); err != nil { - return err - } - return nil -} - -// Convert_v1_Plugin_To_config_Plugin is an autogenerated conversion function. -func Convert_v1_Plugin_To_config_Plugin(in *configv1.Plugin, out *config.Plugin, s conversion.Scope) error { - return autoConvert_v1_Plugin_To_config_Plugin(in, out, s) -} - -func autoConvert_config_Plugin_To_v1_Plugin(in *config.Plugin, out *configv1.Plugin, s conversion.Scope) error { - out.Name = in.Name - if err := metav1.Convert_int32_To_Pointer_int32(&in.Weight, &out.Weight, s); err != nil { - return err - } - return nil -} - -// Convert_config_Plugin_To_v1_Plugin is an autogenerated conversion function. -func Convert_config_Plugin_To_v1_Plugin(in *config.Plugin, out *configv1.Plugin, s conversion.Scope) error { - return autoConvert_config_Plugin_To_v1_Plugin(in, out, s) -} - -func autoConvert_v1_PluginConfig_To_config_PluginConfig(in *configv1.PluginConfig, out *config.PluginConfig, s conversion.Scope) error { - out.Name = in.Name - if err := runtime.Convert_runtime_RawExtension_To_runtime_Object(&in.Args, &out.Args, s); err != nil { - return err - } - return nil -} - -// Convert_v1_PluginConfig_To_config_PluginConfig is an autogenerated conversion function. -func Convert_v1_PluginConfig_To_config_PluginConfig(in *configv1.PluginConfig, out *config.PluginConfig, s conversion.Scope) error { - return autoConvert_v1_PluginConfig_To_config_PluginConfig(in, out, s) -} - -func autoConvert_config_PluginConfig_To_v1_PluginConfig(in *config.PluginConfig, out *configv1.PluginConfig, s conversion.Scope) error { - out.Name = in.Name - if err := runtime.Convert_runtime_Object_To_runtime_RawExtension(&in.Args, &out.Args, s); err != nil { - return err - } - return nil -} - -// Convert_config_PluginConfig_To_v1_PluginConfig is an autogenerated conversion function. -func Convert_config_PluginConfig_To_v1_PluginConfig(in *config.PluginConfig, out *configv1.PluginConfig, s conversion.Scope) error { - return autoConvert_config_PluginConfig_To_v1_PluginConfig(in, out, s) -} - -func autoConvert_v1_PluginSet_To_config_PluginSet(in *configv1.PluginSet, out *config.PluginSet, s conversion.Scope) error { - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = make([]config.Plugin, len(*in)) - for i := range *in { - if err := Convert_v1_Plugin_To_config_Plugin(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.Enabled = nil - } - if in.Disabled != nil { - in, out := &in.Disabled, &out.Disabled - *out = make([]config.Plugin, len(*in)) - for i := range *in { - if err := Convert_v1_Plugin_To_config_Plugin(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.Disabled = nil - } - return nil -} - -// Convert_v1_PluginSet_To_config_PluginSet is an autogenerated conversion function. -func Convert_v1_PluginSet_To_config_PluginSet(in *configv1.PluginSet, out *config.PluginSet, s conversion.Scope) error { - return autoConvert_v1_PluginSet_To_config_PluginSet(in, out, s) -} - -func autoConvert_config_PluginSet_To_v1_PluginSet(in *config.PluginSet, out *configv1.PluginSet, s conversion.Scope) error { - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = make([]configv1.Plugin, len(*in)) - for i := range *in { - if err := Convert_config_Plugin_To_v1_Plugin(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.Enabled = nil - } - if in.Disabled != nil { - in, out := &in.Disabled, &out.Disabled - *out = make([]configv1.Plugin, len(*in)) - for i := range *in { - if err := Convert_config_Plugin_To_v1_Plugin(&(*in)[i], &(*out)[i], s); err != nil { - return err - } - } - } else { - out.Disabled = nil - } - return nil -} - -// Convert_config_PluginSet_To_v1_PluginSet is an autogenerated conversion function. -func Convert_config_PluginSet_To_v1_PluginSet(in *config.PluginSet, out *configv1.PluginSet, s conversion.Scope) error { - return autoConvert_config_PluginSet_To_v1_PluginSet(in, out, s) -} - -func autoConvert_v1_Plugins_To_config_Plugins(in *configv1.Plugins, out *config.Plugins, s conversion.Scope) error { - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PreEnqueue, &out.PreEnqueue, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.QueueSort, &out.QueueSort, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PreFilter, &out.PreFilter, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.Filter, &out.Filter, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PostFilter, &out.PostFilter, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PreScore, &out.PreScore, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.Score, &out.Score, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.Reserve, &out.Reserve, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.Permit, &out.Permit, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PreBind, &out.PreBind, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.Bind, &out.Bind, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.PostBind, &out.PostBind, s); err != nil { - return err - } - if err := Convert_v1_PluginSet_To_config_PluginSet(&in.MultiPoint, &out.MultiPoint, s); err != nil { - return err - } - return nil -} - -// Convert_v1_Plugins_To_config_Plugins is an autogenerated conversion function. -func Convert_v1_Plugins_To_config_Plugins(in *configv1.Plugins, out *config.Plugins, s conversion.Scope) error { - return autoConvert_v1_Plugins_To_config_Plugins(in, out, s) -} - -func autoConvert_config_Plugins_To_v1_Plugins(in *config.Plugins, out *configv1.Plugins, s conversion.Scope) error { - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PreEnqueue, &out.PreEnqueue, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.QueueSort, &out.QueueSort, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PreFilter, &out.PreFilter, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.Filter, &out.Filter, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PostFilter, &out.PostFilter, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PreScore, &out.PreScore, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.Score, &out.Score, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.Reserve, &out.Reserve, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.Permit, &out.Permit, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PreBind, &out.PreBind, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.Bind, &out.Bind, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.PostBind, &out.PostBind, s); err != nil { - return err - } - if err := Convert_config_PluginSet_To_v1_PluginSet(&in.MultiPoint, &out.MultiPoint, s); err != nil { - return err - } - return nil -} - -// Convert_config_Plugins_To_v1_Plugins is an autogenerated conversion function. -func Convert_config_Plugins_To_v1_Plugins(in *config.Plugins, out *configv1.Plugins, s conversion.Scope) error { - return autoConvert_config_Plugins_To_v1_Plugins(in, out, s) -} - -func autoConvert_v1_PodTopologySpreadArgs_To_config_PodTopologySpreadArgs(in *configv1.PodTopologySpreadArgs, out *config.PodTopologySpreadArgs, s conversion.Scope) error { - out.DefaultConstraints = *(*[]corev1.TopologySpreadConstraint)(unsafe.Pointer(&in.DefaultConstraints)) - out.DefaultingType = config.PodTopologySpreadConstraintsDefaulting(in.DefaultingType) - return nil -} - -// Convert_v1_PodTopologySpreadArgs_To_config_PodTopologySpreadArgs is an autogenerated conversion function. -func Convert_v1_PodTopologySpreadArgs_To_config_PodTopologySpreadArgs(in *configv1.PodTopologySpreadArgs, out *config.PodTopologySpreadArgs, s conversion.Scope) error { - return autoConvert_v1_PodTopologySpreadArgs_To_config_PodTopologySpreadArgs(in, out, s) -} - -func autoConvert_config_PodTopologySpreadArgs_To_v1_PodTopologySpreadArgs(in *config.PodTopologySpreadArgs, out *configv1.PodTopologySpreadArgs, s conversion.Scope) error { - out.DefaultConstraints = *(*[]corev1.TopologySpreadConstraint)(unsafe.Pointer(&in.DefaultConstraints)) - out.DefaultingType = configv1.PodTopologySpreadConstraintsDefaulting(in.DefaultingType) - return nil -} - -// Convert_config_PodTopologySpreadArgs_To_v1_PodTopologySpreadArgs is an autogenerated conversion function. -func Convert_config_PodTopologySpreadArgs_To_v1_PodTopologySpreadArgs(in *config.PodTopologySpreadArgs, out *configv1.PodTopologySpreadArgs, s conversion.Scope) error { - return autoConvert_config_PodTopologySpreadArgs_To_v1_PodTopologySpreadArgs(in, out, s) -} - -func autoConvert_v1_RequestedToCapacityRatioParam_To_config_RequestedToCapacityRatioParam(in *configv1.RequestedToCapacityRatioParam, out *config.RequestedToCapacityRatioParam, s conversion.Scope) error { - out.Shape = *(*[]config.UtilizationShapePoint)(unsafe.Pointer(&in.Shape)) - return nil -} - -// Convert_v1_RequestedToCapacityRatioParam_To_config_RequestedToCapacityRatioParam is an autogenerated conversion function. -func Convert_v1_RequestedToCapacityRatioParam_To_config_RequestedToCapacityRatioParam(in *configv1.RequestedToCapacityRatioParam, out *config.RequestedToCapacityRatioParam, s conversion.Scope) error { - return autoConvert_v1_RequestedToCapacityRatioParam_To_config_RequestedToCapacityRatioParam(in, out, s) -} - -func autoConvert_config_RequestedToCapacityRatioParam_To_v1_RequestedToCapacityRatioParam(in *config.RequestedToCapacityRatioParam, out *configv1.RequestedToCapacityRatioParam, s conversion.Scope) error { - out.Shape = *(*[]configv1.UtilizationShapePoint)(unsafe.Pointer(&in.Shape)) - return nil -} - -// Convert_config_RequestedToCapacityRatioParam_To_v1_RequestedToCapacityRatioParam is an autogenerated conversion function. -func Convert_config_RequestedToCapacityRatioParam_To_v1_RequestedToCapacityRatioParam(in *config.RequestedToCapacityRatioParam, out *configv1.RequestedToCapacityRatioParam, s conversion.Scope) error { - return autoConvert_config_RequestedToCapacityRatioParam_To_v1_RequestedToCapacityRatioParam(in, out, s) -} - -func autoConvert_v1_ResourceSpec_To_config_ResourceSpec(in *configv1.ResourceSpec, out *config.ResourceSpec, s conversion.Scope) error { - out.Name = in.Name - out.Weight = in.Weight - return nil -} - -// Convert_v1_ResourceSpec_To_config_ResourceSpec is an autogenerated conversion function. -func Convert_v1_ResourceSpec_To_config_ResourceSpec(in *configv1.ResourceSpec, out *config.ResourceSpec, s conversion.Scope) error { - return autoConvert_v1_ResourceSpec_To_config_ResourceSpec(in, out, s) -} - -func autoConvert_config_ResourceSpec_To_v1_ResourceSpec(in *config.ResourceSpec, out *configv1.ResourceSpec, s conversion.Scope) error { - out.Name = in.Name - out.Weight = in.Weight - return nil -} - -// Convert_config_ResourceSpec_To_v1_ResourceSpec is an autogenerated conversion function. -func Convert_config_ResourceSpec_To_v1_ResourceSpec(in *config.ResourceSpec, out *configv1.ResourceSpec, s conversion.Scope) error { - return autoConvert_config_ResourceSpec_To_v1_ResourceSpec(in, out, s) -} - -func autoConvert_v1_ScoringStrategy_To_config_ScoringStrategy(in *configv1.ScoringStrategy, out *config.ScoringStrategy, s conversion.Scope) error { - out.Type = config.ScoringStrategyType(in.Type) - out.Resources = *(*[]config.ResourceSpec)(unsafe.Pointer(&in.Resources)) - out.RequestedToCapacityRatio = (*config.RequestedToCapacityRatioParam)(unsafe.Pointer(in.RequestedToCapacityRatio)) - return nil -} - -// Convert_v1_ScoringStrategy_To_config_ScoringStrategy is an autogenerated conversion function. -func Convert_v1_ScoringStrategy_To_config_ScoringStrategy(in *configv1.ScoringStrategy, out *config.ScoringStrategy, s conversion.Scope) error { - return autoConvert_v1_ScoringStrategy_To_config_ScoringStrategy(in, out, s) -} - -func autoConvert_config_ScoringStrategy_To_v1_ScoringStrategy(in *config.ScoringStrategy, out *configv1.ScoringStrategy, s conversion.Scope) error { - out.Type = configv1.ScoringStrategyType(in.Type) - out.Resources = *(*[]configv1.ResourceSpec)(unsafe.Pointer(&in.Resources)) - out.RequestedToCapacityRatio = (*configv1.RequestedToCapacityRatioParam)(unsafe.Pointer(in.RequestedToCapacityRatio)) - return nil -} - -// Convert_config_ScoringStrategy_To_v1_ScoringStrategy is an autogenerated conversion function. -func Convert_config_ScoringStrategy_To_v1_ScoringStrategy(in *config.ScoringStrategy, out *configv1.ScoringStrategy, s conversion.Scope) error { - return autoConvert_config_ScoringStrategy_To_v1_ScoringStrategy(in, out, s) -} - -func autoConvert_v1_UtilizationShapePoint_To_config_UtilizationShapePoint(in *configv1.UtilizationShapePoint, out *config.UtilizationShapePoint, s conversion.Scope) error { - out.Utilization = in.Utilization - out.Score = in.Score - return nil -} - -// Convert_v1_UtilizationShapePoint_To_config_UtilizationShapePoint is an autogenerated conversion function. -func Convert_v1_UtilizationShapePoint_To_config_UtilizationShapePoint(in *configv1.UtilizationShapePoint, out *config.UtilizationShapePoint, s conversion.Scope) error { - return autoConvert_v1_UtilizationShapePoint_To_config_UtilizationShapePoint(in, out, s) -} - -func autoConvert_config_UtilizationShapePoint_To_v1_UtilizationShapePoint(in *config.UtilizationShapePoint, out *configv1.UtilizationShapePoint, s conversion.Scope) error { - out.Utilization = in.Utilization - out.Score = in.Score - return nil -} - -// Convert_config_UtilizationShapePoint_To_v1_UtilizationShapePoint is an autogenerated conversion function. -func Convert_config_UtilizationShapePoint_To_v1_UtilizationShapePoint(in *config.UtilizationShapePoint, out *configv1.UtilizationShapePoint, s conversion.Scope) error { - return autoConvert_config_UtilizationShapePoint_To_v1_UtilizationShapePoint(in, out, s) -} - -func autoConvert_v1_VolumeBindingArgs_To_config_VolumeBindingArgs(in *configv1.VolumeBindingArgs, out *config.VolumeBindingArgs, s conversion.Scope) error { - if err := metav1.Convert_Pointer_int64_To_int64(&in.BindTimeoutSeconds, &out.BindTimeoutSeconds, s); err != nil { - return err - } - out.Shape = *(*[]config.UtilizationShapePoint)(unsafe.Pointer(&in.Shape)) - return nil -} - -// Convert_v1_VolumeBindingArgs_To_config_VolumeBindingArgs is an autogenerated conversion function. -func Convert_v1_VolumeBindingArgs_To_config_VolumeBindingArgs(in *configv1.VolumeBindingArgs, out *config.VolumeBindingArgs, s conversion.Scope) error { - return autoConvert_v1_VolumeBindingArgs_To_config_VolumeBindingArgs(in, out, s) -} - -func autoConvert_config_VolumeBindingArgs_To_v1_VolumeBindingArgs(in *config.VolumeBindingArgs, out *configv1.VolumeBindingArgs, s conversion.Scope) error { - if err := metav1.Convert_int64_To_Pointer_int64(&in.BindTimeoutSeconds, &out.BindTimeoutSeconds, s); err != nil { - return err - } - out.Shape = *(*[]configv1.UtilizationShapePoint)(unsafe.Pointer(&in.Shape)) - return nil -} - -// Convert_config_VolumeBindingArgs_To_v1_VolumeBindingArgs is an autogenerated conversion function. -func Convert_config_VolumeBindingArgs_To_v1_VolumeBindingArgs(in *config.VolumeBindingArgs, out *configv1.VolumeBindingArgs, s conversion.Scope) error { - return autoConvert_config_VolumeBindingArgs_To_v1_VolumeBindingArgs(in, out, s) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.deepcopy.go deleted file mode 100644 index 87181b430..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.deepcopy.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package v1 diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.defaults.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.defaults.go deleted file mode 100644 index 9f86c9192..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/v1/zz_generated.defaults.go +++ /dev/null @@ -1,73 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by defaulter-gen. DO NOT EDIT. - -package v1 - -import ( - runtime "k8s.io/apimachinery/pkg/runtime" - configv1 "k8s.io/kube-scheduler/config/v1" -) - -// RegisterDefaults adds defaulters functions to the given scheme. -// Public to allow building arbitrary schemes. -// All generated defaulters are covering - they call all nested defaulters. -func RegisterDefaults(scheme *runtime.Scheme) error { - scheme.AddTypeDefaultingFunc(&configv1.DefaultPreemptionArgs{}, func(obj interface{}) { SetObjectDefaults_DefaultPreemptionArgs(obj.(*configv1.DefaultPreemptionArgs)) }) - scheme.AddTypeDefaultingFunc(&configv1.InterPodAffinityArgs{}, func(obj interface{}) { SetObjectDefaults_InterPodAffinityArgs(obj.(*configv1.InterPodAffinityArgs)) }) - scheme.AddTypeDefaultingFunc(&configv1.KubeSchedulerConfiguration{}, func(obj interface{}) { - SetObjectDefaults_KubeSchedulerConfiguration(obj.(*configv1.KubeSchedulerConfiguration)) - }) - scheme.AddTypeDefaultingFunc(&configv1.NodeResourcesBalancedAllocationArgs{}, func(obj interface{}) { - SetObjectDefaults_NodeResourcesBalancedAllocationArgs(obj.(*configv1.NodeResourcesBalancedAllocationArgs)) - }) - scheme.AddTypeDefaultingFunc(&configv1.NodeResourcesFitArgs{}, func(obj interface{}) { SetObjectDefaults_NodeResourcesFitArgs(obj.(*configv1.NodeResourcesFitArgs)) }) - scheme.AddTypeDefaultingFunc(&configv1.PodTopologySpreadArgs{}, func(obj interface{}) { SetObjectDefaults_PodTopologySpreadArgs(obj.(*configv1.PodTopologySpreadArgs)) }) - scheme.AddTypeDefaultingFunc(&configv1.VolumeBindingArgs{}, func(obj interface{}) { SetObjectDefaults_VolumeBindingArgs(obj.(*configv1.VolumeBindingArgs)) }) - return nil -} - -func SetObjectDefaults_DefaultPreemptionArgs(in *configv1.DefaultPreemptionArgs) { - SetDefaults_DefaultPreemptionArgs(in) -} - -func SetObjectDefaults_InterPodAffinityArgs(in *configv1.InterPodAffinityArgs) { - SetDefaults_InterPodAffinityArgs(in) -} - -func SetObjectDefaults_KubeSchedulerConfiguration(in *configv1.KubeSchedulerConfiguration) { - SetDefaults_KubeSchedulerConfiguration(in) -} - -func SetObjectDefaults_NodeResourcesBalancedAllocationArgs(in *configv1.NodeResourcesBalancedAllocationArgs) { - SetDefaults_NodeResourcesBalancedAllocationArgs(in) -} - -func SetObjectDefaults_NodeResourcesFitArgs(in *configv1.NodeResourcesFitArgs) { - SetDefaults_NodeResourcesFitArgs(in) -} - -func SetObjectDefaults_PodTopologySpreadArgs(in *configv1.PodTopologySpreadArgs) { - SetDefaults_PodTopologySpreadArgs(in) -} - -func SetObjectDefaults_VolumeBindingArgs(in *configv1.VolumeBindingArgs) { - SetDefaults_VolumeBindingArgs(in) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation.go deleted file mode 100644 index 2f67fa629..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation.go +++ /dev/null @@ -1,296 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package validation - -import ( - "fmt" - "reflect" - - v1 "k8s.io/api/core/v1" - apiequality "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/runtime" - utilerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/validation" - "k8s.io/apimachinery/pkg/util/validation/field" - componentbasevalidation "k8s.io/component-base/config/validation" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - "k8s.io/kubernetes/pkg/scheduler/apis/config" -) - -// ValidateKubeSchedulerConfiguration ensures validation of the KubeSchedulerConfiguration struct -func ValidateKubeSchedulerConfiguration(cc *config.KubeSchedulerConfiguration) utilerrors.Aggregate { - var errs []error - errs = append(errs, componentbasevalidation.ValidateClientConnectionConfiguration(&cc.ClientConnection, field.NewPath("clientConnection")).ToAggregate()) - errs = append(errs, componentbasevalidation.ValidateLeaderElectionConfiguration(&cc.LeaderElection, field.NewPath("leaderElection")).ToAggregate()) - - // TODO: This can be removed when ResourceLock is not available - // Only ResourceLock values with leases are allowed - if cc.LeaderElection.LeaderElect && cc.LeaderElection.ResourceLock != "leases" { - leaderElectionPath := field.NewPath("leaderElection") - errs = append(errs, field.Invalid(leaderElectionPath.Child("resourceLock"), cc.LeaderElection.ResourceLock, `resourceLock value must be "leases"`)) - } - - profilesPath := field.NewPath("profiles") - if cc.Parallelism <= 0 { - errs = append(errs, field.Invalid(field.NewPath("parallelism"), cc.Parallelism, "should be an integer value greater than zero")) - } - - if len(cc.Profiles) == 0 { - errs = append(errs, field.Required(profilesPath, "")) - } else { - existingProfiles := make(map[string]int, len(cc.Profiles)) - for i := range cc.Profiles { - profile := &cc.Profiles[i] - path := profilesPath.Index(i) - errs = append(errs, validateKubeSchedulerProfile(path, cc.APIVersion, profile)...) - if idx, ok := existingProfiles[profile.SchedulerName]; ok { - errs = append(errs, field.Duplicate(path.Child("schedulerName"), profilesPath.Index(idx).Child("schedulerName"))) - } - existingProfiles[profile.SchedulerName] = i - } - errs = append(errs, validateCommonQueueSort(profilesPath, cc.Profiles)...) - } - - errs = append(errs, validatePercentageOfNodesToScore(field.NewPath("percentageOfNodesToScore"), cc.PercentageOfNodesToScore)) - - if cc.PodInitialBackoffSeconds <= 0 { - errs = append(errs, field.Invalid(field.NewPath("podInitialBackoffSeconds"), - cc.PodInitialBackoffSeconds, "must be greater than 0")) - } - if cc.PodMaxBackoffSeconds < cc.PodInitialBackoffSeconds { - errs = append(errs, field.Invalid(field.NewPath("podMaxBackoffSeconds"), - cc.PodMaxBackoffSeconds, "must be greater than or equal to PodInitialBackoffSeconds")) - } - - errs = append(errs, validateExtenders(field.NewPath("extenders"), cc.Extenders)...) - return utilerrors.Flatten(utilerrors.NewAggregate(errs)) -} - -func validatePercentageOfNodesToScore(path *field.Path, percentageOfNodesToScore *int32) error { - if percentageOfNodesToScore != nil { - if *percentageOfNodesToScore < 0 || *percentageOfNodesToScore > 100 { - return field.Invalid(path, *percentageOfNodesToScore, "not in valid range [0-100]") - } - } - return nil -} - -type invalidPlugins struct { - schemeGroupVersion string - plugins []string -} - -// invalidPluginsByVersion maintains a list of removed/deprecated plugins in each version. -// Remember to add an entry to that list when creating a new component config -// version (even if the list of invalid plugins is empty). -var invalidPluginsByVersion = []invalidPlugins{ - { - schemeGroupVersion: v1.SchemeGroupVersion.String(), - plugins: []string{ - "AzureDiskLimits", - "CinderLimits", - "EBSLimits", - "GCEPDLimits", - }, - }, -} - -// isPluginInvalid checks if a given plugin was removed/deprecated in the given component -// config version or earlier. -func isPluginInvalid(apiVersion string, name string) (bool, string) { - for _, dp := range invalidPluginsByVersion { - for _, plugin := range dp.plugins { - if name == plugin { - return true, dp.schemeGroupVersion - } - } - if apiVersion == dp.schemeGroupVersion { - break - } - } - return false, "" -} - -func validatePluginSetForInvalidPlugins(path *field.Path, apiVersion string, ps config.PluginSet) []error { - var errs []error - for i, plugin := range ps.Enabled { - if invalid, invalidVersion := isPluginInvalid(apiVersion, plugin.Name); invalid { - errs = append(errs, field.Invalid(path.Child("enabled").Index(i), plugin.Name, fmt.Sprintf("was invalid in version %q (KubeSchedulerConfiguration is version %q)", invalidVersion, apiVersion))) - } - } - return errs -} - -func validateKubeSchedulerProfile(path *field.Path, apiVersion string, profile *config.KubeSchedulerProfile) []error { - var errs []error - if len(profile.SchedulerName) == 0 { - errs = append(errs, field.Required(path.Child("schedulerName"), "")) - } - errs = append(errs, validatePercentageOfNodesToScore(path.Child("percentageOfNodesToScore"), profile.PercentageOfNodesToScore)) - errs = append(errs, validatePluginConfig(path, apiVersion, profile)...) - return errs -} - -func validatePluginConfig(path *field.Path, apiVersion string, profile *config.KubeSchedulerProfile) []error { - var errs []error - m := map[string]interface{}{ - "DefaultPreemption": ValidateDefaultPreemptionArgs, - "InterPodAffinity": ValidateInterPodAffinityArgs, - "NodeAffinity": ValidateNodeAffinityArgs, - "NodeResourcesBalancedAllocation": ValidateNodeResourcesBalancedAllocationArgs, - "NodeResourcesFitArgs": ValidateNodeResourcesFitArgs, - "PodTopologySpread": ValidatePodTopologySpreadArgs, - "VolumeBinding": ValidateVolumeBindingArgs, - } - - if profile.Plugins != nil { - stagesToPluginSet := map[string]config.PluginSet{ - "preEnqueue": profile.Plugins.PreEnqueue, - "queueSort": profile.Plugins.QueueSort, - "preFilter": profile.Plugins.PreFilter, - "filter": profile.Plugins.Filter, - "postFilter": profile.Plugins.PostFilter, - "preScore": profile.Plugins.PreScore, - "score": profile.Plugins.Score, - "reserve": profile.Plugins.Reserve, - "permit": profile.Plugins.Permit, - "preBind": profile.Plugins.PreBind, - "bind": profile.Plugins.Bind, - "postBind": profile.Plugins.PostBind, - } - - pluginsPath := path.Child("plugins") - for s, p := range stagesToPluginSet { - errs = append(errs, validatePluginSetForInvalidPlugins( - pluginsPath.Child(s), apiVersion, p)...) - } - } - - seenPluginConfig := sets.New[string]() - - for i := range profile.PluginConfig { - pluginConfigPath := path.Child("pluginConfig").Index(i) - name := profile.PluginConfig[i].Name - args := profile.PluginConfig[i].Args - if seenPluginConfig.Has(name) { - errs = append(errs, field.Duplicate(pluginConfigPath, name)) - } else { - seenPluginConfig.Insert(name) - } - if invalid, invalidVersion := isPluginInvalid(apiVersion, name); invalid { - errs = append(errs, field.Invalid(pluginConfigPath, name, fmt.Sprintf("was invalid in version %q (KubeSchedulerConfiguration is version %q)", invalidVersion, apiVersion))) - } else if validateFunc, ok := m[name]; ok { - // type mismatch, no need to validate the `args`. - if reflect.TypeOf(args) != reflect.ValueOf(validateFunc).Type().In(1) { - errs = append(errs, field.Invalid(pluginConfigPath.Child("args"), args, "has to match plugin args")) - } else { - in := []reflect.Value{reflect.ValueOf(pluginConfigPath.Child("args")), reflect.ValueOf(args)} - res := reflect.ValueOf(validateFunc).Call(in) - // It's possible that validation function return a Aggregate, just append here and it will be flattened at the end of CC validation. - if res[0].Interface() != nil { - errs = append(errs, res[0].Interface().(error)) - } - } - } - } - return errs -} - -func validateCommonQueueSort(path *field.Path, profiles []config.KubeSchedulerProfile) []error { - var errs []error - var canon config.PluginSet - var queueSortName string - var queueSortArgs runtime.Object - if profiles[0].Plugins != nil { - canon = profiles[0].Plugins.QueueSort - if len(profiles[0].Plugins.QueueSort.Enabled) != 0 { - queueSortName = profiles[0].Plugins.QueueSort.Enabled[0].Name - } - length := len(profiles[0].Plugins.QueueSort.Enabled) - if length > 1 { - errs = append(errs, field.Invalid(path.Index(0).Child("plugins", "queueSort", "Enabled"), length, "only one queue sort plugin can be enabled")) - } - } - for _, cfg := range profiles[0].PluginConfig { - if len(queueSortName) > 0 && cfg.Name == queueSortName { - queueSortArgs = cfg.Args - } - } - for i := 1; i < len(profiles); i++ { - var curr config.PluginSet - if profiles[i].Plugins != nil { - curr = profiles[i].Plugins.QueueSort - } - if !apiequality.Semantic.DeepEqual(canon, curr) { - errs = append(errs, field.Invalid(path.Index(i).Child("plugins", "queueSort"), curr, "queueSort must be the same for all profiles")) - } - for _, cfg := range profiles[i].PluginConfig { - if cfg.Name == queueSortName && !apiequality.Semantic.DeepEqual(queueSortArgs, cfg.Args) { - errs = append(errs, field.Invalid(path.Index(i).Child("pluginConfig", "args"), cfg.Args, "queueSort must be the same for all profiles")) - } - } - } - return errs -} - -// validateExtenders validates the configured extenders for the Scheduler -func validateExtenders(fldPath *field.Path, extenders []config.Extender) []error { - var errs []error - binders := 0 - extenderManagedResources := sets.New[string]() - for i, extender := range extenders { - path := fldPath.Index(i) - if len(extender.PrioritizeVerb) > 0 && extender.Weight <= 0 { - errs = append(errs, field.Invalid(path.Child("weight"), - extender.Weight, "must have a positive weight applied to it")) - } - if extender.BindVerb != "" { - binders++ - } - for j, resource := range extender.ManagedResources { - managedResourcesPath := path.Child("managedResources").Index(j) - validationErrors := validateExtendedResourceName(managedResourcesPath.Child("name"), v1.ResourceName(resource.Name)) - errs = append(errs, validationErrors...) - if extenderManagedResources.Has(resource.Name) { - errs = append(errs, field.Invalid(managedResourcesPath.Child("name"), - resource.Name, "duplicate extender managed resource name")) - } - extenderManagedResources.Insert(resource.Name) - } - } - if binders > 1 { - errs = append(errs, field.Invalid(fldPath, fmt.Sprintf("found %d extenders implementing bind", binders), "only one extender can implement bind")) - } - return errs -} - -// validateExtendedResourceName checks whether the specified name is a valid -// extended resource name. -func validateExtendedResourceName(path *field.Path, name v1.ResourceName) []error { - var validationErrors []error - for _, msg := range validation.IsQualifiedName(string(name)) { - validationErrors = append(validationErrors, field.Invalid(path, name, msg)) - } - if len(validationErrors) != 0 { - return validationErrors - } - if !v1helper.IsExtendedResourceName(name) { - validationErrors = append(validationErrors, field.Invalid(path, string(name), "is an invalid extended resource name")) - } - return validationErrors -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go deleted file mode 100644 index e3797dc87..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/validation/validation_pluginargs.go +++ /dev/null @@ -1,329 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package validation - -import ( - "fmt" - "strings" - - v1 "k8s.io/api/core/v1" - metav1validation "k8s.io/apimachinery/pkg/apis/meta/v1/validation" - "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/validation/field" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/scheduler/apis/config" -) - -// supportedScoringStrategyTypes has to be a set of strings for use with field.Unsupported -var supportedScoringStrategyTypes = sets.New( - string(config.LeastAllocated), - string(config.MostAllocated), - string(config.RequestedToCapacityRatio), -) - -// ValidateDefaultPreemptionArgs validates that DefaultPreemptionArgs are correct. -func ValidateDefaultPreemptionArgs(path *field.Path, args *config.DefaultPreemptionArgs) error { - var allErrs field.ErrorList - percentagePath := path.Child("minCandidateNodesPercentage") - absolutePath := path.Child("minCandidateNodesAbsolute") - if err := validateMinCandidateNodesPercentage(args.MinCandidateNodesPercentage, percentagePath); err != nil { - allErrs = append(allErrs, err) - } - if err := validateMinCandidateNodesAbsolute(args.MinCandidateNodesAbsolute, absolutePath); err != nil { - allErrs = append(allErrs, err) - } - if args.MinCandidateNodesPercentage == 0 && args.MinCandidateNodesAbsolute == 0 { - allErrs = append(allErrs, - field.Invalid(percentagePath, args.MinCandidateNodesPercentage, "cannot be zero at the same time as minCandidateNodesAbsolute"), - field.Invalid(absolutePath, args.MinCandidateNodesAbsolute, "cannot be zero at the same time as minCandidateNodesPercentage")) - } - return allErrs.ToAggregate() -} - -// validateMinCandidateNodesPercentage validates that -// minCandidateNodesPercentage is within the allowed range. -func validateMinCandidateNodesPercentage(minCandidateNodesPercentage int32, p *field.Path) *field.Error { - if minCandidateNodesPercentage < 0 || minCandidateNodesPercentage > 100 { - return field.Invalid(p, minCandidateNodesPercentage, "not in valid range [0, 100]") - } - return nil -} - -// validateMinCandidateNodesAbsolute validates that minCandidateNodesAbsolute -// is within the allowed range. -func validateMinCandidateNodesAbsolute(minCandidateNodesAbsolute int32, p *field.Path) *field.Error { - if minCandidateNodesAbsolute < 0 { - return field.Invalid(p, minCandidateNodesAbsolute, "not in valid range [0, inf)") - } - return nil -} - -// ValidateInterPodAffinityArgs validates that InterPodAffinityArgs are correct. -func ValidateInterPodAffinityArgs(path *field.Path, args *config.InterPodAffinityArgs) error { - return validateHardPodAffinityWeight(path.Child("hardPodAffinityWeight"), args.HardPodAffinityWeight) -} - -// validateHardPodAffinityWeight validates that weight is within allowed range. -func validateHardPodAffinityWeight(path *field.Path, w int32) error { - const ( - minHardPodAffinityWeight = 0 - maxHardPodAffinityWeight = 100 - ) - - if w < minHardPodAffinityWeight || w > maxHardPodAffinityWeight { - msg := fmt.Sprintf("not in valid range [%d, %d]", minHardPodAffinityWeight, maxHardPodAffinityWeight) - return field.Invalid(path, w, msg) - } - return nil -} - -// ValidatePodTopologySpreadArgs validates that PodTopologySpreadArgs are correct. -// It replicates the validation from pkg/apis/core/validation.validateTopologySpreadConstraints -// with an additional check for .labelSelector to be nil. -func ValidatePodTopologySpreadArgs(path *field.Path, args *config.PodTopologySpreadArgs) error { - var allErrs field.ErrorList - if err := validateDefaultingType(path.Child("defaultingType"), args.DefaultingType, args.DefaultConstraints); err != nil { - allErrs = append(allErrs, err) - } - - defaultConstraintsPath := path.Child("defaultConstraints") - for i, c := range args.DefaultConstraints { - p := defaultConstraintsPath.Index(i) - if c.MaxSkew <= 0 { - f := p.Child("maxSkew") - allErrs = append(allErrs, field.Invalid(f, c.MaxSkew, "not in valid range (0, inf)")) - } - allErrs = append(allErrs, validateTopologyKey(p.Child("topologyKey"), c.TopologyKey)...) - if err := validateWhenUnsatisfiable(p.Child("whenUnsatisfiable"), c.WhenUnsatisfiable); err != nil { - allErrs = append(allErrs, err) - } - if c.LabelSelector != nil { - f := field.Forbidden(p.Child("labelSelector"), "constraint must not define a selector, as they deduced for each pod") - allErrs = append(allErrs, f) - } - if err := validateConstraintNotRepeat(defaultConstraintsPath, args.DefaultConstraints, i); err != nil { - allErrs = append(allErrs, err) - } - } - if len(allErrs) == 0 { - return nil - } - return allErrs.ToAggregate() -} - -func validateDefaultingType(p *field.Path, v config.PodTopologySpreadConstraintsDefaulting, constraints []v1.TopologySpreadConstraint) *field.Error { - if v != config.SystemDefaulting && v != config.ListDefaulting { - return field.NotSupported(p, v, []string{string(config.SystemDefaulting), string(config.ListDefaulting)}) - } - if v == config.SystemDefaulting && len(constraints) > 0 { - return field.Invalid(p, v, "when .defaultConstraints are not empty") - } - return nil -} - -func validateTopologyKey(p *field.Path, v string) field.ErrorList { - var allErrs field.ErrorList - if len(v) == 0 { - allErrs = append(allErrs, field.Required(p, "can not be empty")) - } else { - allErrs = append(allErrs, metav1validation.ValidateLabelName(v, p)...) - } - return allErrs -} - -func validateWhenUnsatisfiable(p *field.Path, v v1.UnsatisfiableConstraintAction) *field.Error { - supportedScheduleActions := sets.New(string(v1.DoNotSchedule), string(v1.ScheduleAnyway)) - - if len(v) == 0 { - return field.Required(p, "can not be empty") - } - if !supportedScheduleActions.Has(string(v)) { - return field.NotSupported(p, v, sets.List(supportedScheduleActions)) - } - return nil -} - -func validateConstraintNotRepeat(path *field.Path, constraints []v1.TopologySpreadConstraint, idx int) *field.Error { - c := &constraints[idx] - for i := range constraints[:idx] { - other := &constraints[i] - if c.TopologyKey == other.TopologyKey && c.WhenUnsatisfiable == other.WhenUnsatisfiable { - return field.Duplicate(path.Index(idx), fmt.Sprintf("{%v, %v}", c.TopologyKey, c.WhenUnsatisfiable)) - } - } - return nil -} - -func validateFunctionShape(shape []config.UtilizationShapePoint, path *field.Path) field.ErrorList { - const ( - minUtilization = 0 - maxUtilization = 100 - minScore = 0 - maxScore = int32(config.MaxCustomPriorityScore) - ) - - var allErrs field.ErrorList - - if len(shape) == 0 { - allErrs = append(allErrs, field.Required(path, "at least one point must be specified")) - return allErrs - } - - for i := 1; i < len(shape); i++ { - if shape[i-1].Utilization >= shape[i].Utilization { - allErrs = append(allErrs, field.Invalid(path.Index(i).Child("utilization"), shape[i].Utilization, "utilization values must be sorted in increasing order")) - break - } - } - - for i, point := range shape { - if point.Utilization < minUtilization || point.Utilization > maxUtilization { - msg := fmt.Sprintf("not in valid range [%d, %d]", minUtilization, maxUtilization) - allErrs = append(allErrs, field.Invalid(path.Index(i).Child("utilization"), point.Utilization, msg)) - } - - if point.Score < minScore || point.Score > maxScore { - msg := fmt.Sprintf("not in valid range [%d, %d]", minScore, maxScore) - allErrs = append(allErrs, field.Invalid(path.Index(i).Child("score"), point.Score, msg)) - } - } - - return allErrs -} - -func validateResources(resources []config.ResourceSpec, p *field.Path) field.ErrorList { - var allErrs field.ErrorList - for i, resource := range resources { - if resource.Weight <= 0 || resource.Weight > 100 { - msg := fmt.Sprintf("resource weight of %v not in valid range (0, 100]", resource.Name) - allErrs = append(allErrs, field.Invalid(p.Index(i).Child("weight"), resource.Weight, msg)) - } - } - return allErrs -} - -// ValidateNodeResourcesBalancedAllocationArgs validates that NodeResourcesBalancedAllocationArgs are set correctly. -func ValidateNodeResourcesBalancedAllocationArgs(path *field.Path, args *config.NodeResourcesBalancedAllocationArgs) error { - var allErrs field.ErrorList - seenResources := sets.New[string]() - for i, resource := range args.Resources { - if seenResources.Has(resource.Name) { - allErrs = append(allErrs, field.Duplicate(path.Child("resources").Index(i).Child("name"), resource.Name)) - } else { - seenResources.Insert(resource.Name) - } - if resource.Weight != 1 { - allErrs = append(allErrs, field.Invalid(path.Child("resources").Index(i).Child("weight"), resource.Weight, "must be 1")) - } - } - return allErrs.ToAggregate() -} - -// ValidateNodeAffinityArgs validates that NodeAffinityArgs are correct. -func ValidateNodeAffinityArgs(path *field.Path, args *config.NodeAffinityArgs) error { - if args.AddedAffinity == nil { - return nil - } - affinity := args.AddedAffinity - var errs []error - if ns := affinity.RequiredDuringSchedulingIgnoredDuringExecution; ns != nil { - _, err := nodeaffinity.NewNodeSelector(ns, field.WithPath(path.Child("addedAffinity", "requiredDuringSchedulingIgnoredDuringExecution"))) - if err != nil { - errs = append(errs, err) - } - } - // TODO: Add validation for requiredDuringSchedulingRequiredDuringExecution when it gets added to the API. - if terms := affinity.PreferredDuringSchedulingIgnoredDuringExecution; len(terms) != 0 { - _, err := nodeaffinity.NewPreferredSchedulingTerms(terms, field.WithPath(path.Child("addedAffinity", "preferredDuringSchedulingIgnoredDuringExecution"))) - if err != nil { - errs = append(errs, err) - } - } - return errors.Flatten(errors.NewAggregate(errs)) -} - -// VolumeBindingArgsValidationOptions contains the different settings for validation. -type VolumeBindingArgsValidationOptions struct { - AllowStorageCapacityScoring bool -} - -// ValidateVolumeBindingArgs validates that VolumeBindingArgs are set correctly. -func ValidateVolumeBindingArgs(path *field.Path, args *config.VolumeBindingArgs) error { - return ValidateVolumeBindingArgsWithOptions(path, args, VolumeBindingArgsValidationOptions{ - AllowStorageCapacityScoring: utilfeature.DefaultFeatureGate.Enabled(features.StorageCapacityScoring), - }) -} - -// ValidateVolumeBindingArgsWithOptions validates that VolumeBindingArgs and VolumeBindingArgsValidationOptions with scheduler features. -func ValidateVolumeBindingArgsWithOptions(path *field.Path, args *config.VolumeBindingArgs, opts VolumeBindingArgsValidationOptions) error { - var allErrs field.ErrorList - - if args.BindTimeoutSeconds < 0 { - allErrs = append(allErrs, field.Invalid(path.Child("bindTimeoutSeconds"), args.BindTimeoutSeconds, "invalid BindTimeoutSeconds, should not be a negative value")) - } - - if opts.AllowStorageCapacityScoring { - allErrs = append(allErrs, validateFunctionShape(args.Shape, path.Child("shape"))...) - } else if args.Shape != nil { - // When the feature is off, return an error if the config is not nil. - // This prevents unexpected configuration from taking effect when the - // feature turns on in the future. - allErrs = append(allErrs, field.Invalid(path.Child("shape"), args.Shape, "unexpected field `shape`, remove it or turn on the feature gate StorageCapacityScoring")) - } - return allErrs.ToAggregate() -} - -func ValidateNodeResourcesFitArgs(path *field.Path, args *config.NodeResourcesFitArgs) error { - var allErrs field.ErrorList - resPath := path.Child("ignoredResources") - for i, res := range args.IgnoredResources { - path := resPath.Index(i) - if errs := metav1validation.ValidateLabelName(res, path); len(errs) != 0 { - allErrs = append(allErrs, errs...) - } - } - - groupPath := path.Child("ignoredResourceGroups") - for i, group := range args.IgnoredResourceGroups { - path := groupPath.Index(i) - if strings.Contains(group, "/") { - allErrs = append(allErrs, field.Invalid(path, group, "resource group name can't contain '/'")) - } - if errs := metav1validation.ValidateLabelName(group, path); len(errs) != 0 { - allErrs = append(allErrs, errs...) - } - } - - strategyPath := path.Child("scoringStrategy") - if args.ScoringStrategy != nil { - if !supportedScoringStrategyTypes.Has(string(args.ScoringStrategy.Type)) { - allErrs = append(allErrs, field.NotSupported(strategyPath.Child("type"), args.ScoringStrategy.Type, sets.List(supportedScoringStrategyTypes))) - } - allErrs = append(allErrs, validateResources(args.ScoringStrategy.Resources, strategyPath.Child("resources"))...) - if args.ScoringStrategy.RequestedToCapacityRatio != nil { - allErrs = append(allErrs, validateFunctionShape(args.ScoringStrategy.RequestedToCapacityRatio.Shape, strategyPath.Child("shape"))...) - } - } - - if len(allErrs) == 0 { - return nil - } - return allErrs.ToAggregate() -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go b/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go deleted file mode 100644 index f5baa6221..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/apis/config/zz_generated.deepcopy.go +++ /dev/null @@ -1,562 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -/* -Copyright The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Code generated by deepcopy-gen. DO NOT EDIT. - -package config - -import ( - v1 "k8s.io/api/core/v1" - runtime "k8s.io/apimachinery/pkg/runtime" -) - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DefaultPreemptionArgs) DeepCopyInto(out *DefaultPreemptionArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DefaultPreemptionArgs. -func (in *DefaultPreemptionArgs) DeepCopy() *DefaultPreemptionArgs { - if in == nil { - return nil - } - out := new(DefaultPreemptionArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DefaultPreemptionArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Extender) DeepCopyInto(out *Extender) { - *out = *in - if in.TLSConfig != nil { - in, out := &in.TLSConfig, &out.TLSConfig - *out = new(ExtenderTLSConfig) - (*in).DeepCopyInto(*out) - } - out.HTTPTimeout = in.HTTPTimeout - if in.ManagedResources != nil { - in, out := &in.ManagedResources, &out.ManagedResources - *out = make([]ExtenderManagedResource, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Extender. -func (in *Extender) DeepCopy() *Extender { - if in == nil { - return nil - } - out := new(Extender) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExtenderManagedResource) DeepCopyInto(out *ExtenderManagedResource) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderManagedResource. -func (in *ExtenderManagedResource) DeepCopy() *ExtenderManagedResource { - if in == nil { - return nil - } - out := new(ExtenderManagedResource) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ExtenderTLSConfig) DeepCopyInto(out *ExtenderTLSConfig) { - *out = *in - if in.CertData != nil { - in, out := &in.CertData, &out.CertData - *out = make([]byte, len(*in)) - copy(*out, *in) - } - if in.KeyData != nil { - in, out := &in.KeyData, &out.KeyData - *out = make([]byte, len(*in)) - copy(*out, *in) - } - if in.CAData != nil { - in, out := &in.CAData, &out.CAData - *out = make([]byte, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExtenderTLSConfig. -func (in *ExtenderTLSConfig) DeepCopy() *ExtenderTLSConfig { - if in == nil { - return nil - } - out := new(ExtenderTLSConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *InterPodAffinityArgs) DeepCopyInto(out *InterPodAffinityArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InterPodAffinityArgs. -func (in *InterPodAffinityArgs) DeepCopy() *InterPodAffinityArgs { - if in == nil { - return nil - } - out := new(InterPodAffinityArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *InterPodAffinityArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubeSchedulerConfiguration) DeepCopyInto(out *KubeSchedulerConfiguration) { - *out = *in - out.TypeMeta = in.TypeMeta - out.LeaderElection = in.LeaderElection - out.ClientConnection = in.ClientConnection - out.DebuggingConfiguration = in.DebuggingConfiguration - if in.PercentageOfNodesToScore != nil { - in, out := &in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore - *out = new(int32) - **out = **in - } - if in.Profiles != nil { - in, out := &in.Profiles, &out.Profiles - *out = make([]KubeSchedulerProfile, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - if in.Extenders != nil { - in, out := &in.Extenders, &out.Extenders - *out = make([]Extender, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSchedulerConfiguration. -func (in *KubeSchedulerConfiguration) DeepCopy() *KubeSchedulerConfiguration { - if in == nil { - return nil - } - out := new(KubeSchedulerConfiguration) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *KubeSchedulerConfiguration) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KubeSchedulerProfile) DeepCopyInto(out *KubeSchedulerProfile) { - *out = *in - if in.PercentageOfNodesToScore != nil { - in, out := &in.PercentageOfNodesToScore, &out.PercentageOfNodesToScore - *out = new(int32) - **out = **in - } - if in.Plugins != nil { - in, out := &in.Plugins, &out.Plugins - *out = new(Plugins) - (*in).DeepCopyInto(*out) - } - if in.PluginConfig != nil { - in, out := &in.PluginConfig, &out.PluginConfig - *out = make([]PluginConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubeSchedulerProfile. -func (in *KubeSchedulerProfile) DeepCopy() *KubeSchedulerProfile { - if in == nil { - return nil - } - out := new(KubeSchedulerProfile) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeAffinityArgs) DeepCopyInto(out *NodeAffinityArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - if in.AddedAffinity != nil { - in, out := &in.AddedAffinity, &out.AddedAffinity - *out = new(v1.NodeAffinity) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeAffinityArgs. -func (in *NodeAffinityArgs) DeepCopy() *NodeAffinityArgs { - if in == nil { - return nil - } - out := new(NodeAffinityArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeAffinityArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeResourcesBalancedAllocationArgs) DeepCopyInto(out *NodeResourcesBalancedAllocationArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]ResourceSpec, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourcesBalancedAllocationArgs. -func (in *NodeResourcesBalancedAllocationArgs) DeepCopy() *NodeResourcesBalancedAllocationArgs { - if in == nil { - return nil - } - out := new(NodeResourcesBalancedAllocationArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeResourcesBalancedAllocationArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *NodeResourcesFitArgs) DeepCopyInto(out *NodeResourcesFitArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - if in.IgnoredResources != nil { - in, out := &in.IgnoredResources, &out.IgnoredResources - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.IgnoredResourceGroups != nil { - in, out := &in.IgnoredResourceGroups, &out.IgnoredResourceGroups - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.ScoringStrategy != nil { - in, out := &in.ScoringStrategy, &out.ScoringStrategy - *out = new(ScoringStrategy) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourcesFitArgs. -func (in *NodeResourcesFitArgs) DeepCopy() *NodeResourcesFitArgs { - if in == nil { - return nil - } - out := new(NodeResourcesFitArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *NodeResourcesFitArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Plugin) DeepCopyInto(out *Plugin) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugin. -func (in *Plugin) DeepCopy() *Plugin { - if in == nil { - return nil - } - out := new(Plugin) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PluginConfig) DeepCopyInto(out *PluginConfig) { - *out = *in - if in.Args != nil { - out.Args = in.Args.DeepCopyObject() - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginConfig. -func (in *PluginConfig) DeepCopy() *PluginConfig { - if in == nil { - return nil - } - out := new(PluginConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PluginSet) DeepCopyInto(out *PluginSet) { - *out = *in - if in.Enabled != nil { - in, out := &in.Enabled, &out.Enabled - *out = make([]Plugin, len(*in)) - copy(*out, *in) - } - if in.Disabled != nil { - in, out := &in.Disabled, &out.Disabled - *out = make([]Plugin, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginSet. -func (in *PluginSet) DeepCopy() *PluginSet { - if in == nil { - return nil - } - out := new(PluginSet) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Plugins) DeepCopyInto(out *Plugins) { - *out = *in - in.PreEnqueue.DeepCopyInto(&out.PreEnqueue) - in.QueueSort.DeepCopyInto(&out.QueueSort) - in.PreFilter.DeepCopyInto(&out.PreFilter) - in.Filter.DeepCopyInto(&out.Filter) - in.PostFilter.DeepCopyInto(&out.PostFilter) - in.PreScore.DeepCopyInto(&out.PreScore) - in.Score.DeepCopyInto(&out.Score) - in.Reserve.DeepCopyInto(&out.Reserve) - in.Permit.DeepCopyInto(&out.Permit) - in.PreBind.DeepCopyInto(&out.PreBind) - in.Bind.DeepCopyInto(&out.Bind) - in.PostBind.DeepCopyInto(&out.PostBind) - in.MultiPoint.DeepCopyInto(&out.MultiPoint) - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Plugins. -func (in *Plugins) DeepCopy() *Plugins { - if in == nil { - return nil - } - out := new(Plugins) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PodTopologySpreadArgs) DeepCopyInto(out *PodTopologySpreadArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - if in.DefaultConstraints != nil { - in, out := &in.DefaultConstraints, &out.DefaultConstraints - *out = make([]v1.TopologySpreadConstraint, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodTopologySpreadArgs. -func (in *PodTopologySpreadArgs) DeepCopy() *PodTopologySpreadArgs { - if in == nil { - return nil - } - out := new(PodTopologySpreadArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PodTopologySpreadArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *RequestedToCapacityRatioParam) DeepCopyInto(out *RequestedToCapacityRatioParam) { - *out = *in - if in.Shape != nil { - in, out := &in.Shape, &out.Shape - *out = make([]UtilizationShapePoint, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RequestedToCapacityRatioParam. -func (in *RequestedToCapacityRatioParam) DeepCopy() *RequestedToCapacityRatioParam { - if in == nil { - return nil - } - out := new(RequestedToCapacityRatioParam) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ResourceSpec) DeepCopyInto(out *ResourceSpec) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ResourceSpec. -func (in *ResourceSpec) DeepCopy() *ResourceSpec { - if in == nil { - return nil - } - out := new(ResourceSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ScoringStrategy) DeepCopyInto(out *ScoringStrategy) { - *out = *in - if in.Resources != nil { - in, out := &in.Resources, &out.Resources - *out = make([]ResourceSpec, len(*in)) - copy(*out, *in) - } - if in.RequestedToCapacityRatio != nil { - in, out := &in.RequestedToCapacityRatio, &out.RequestedToCapacityRatio - *out = new(RequestedToCapacityRatioParam) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ScoringStrategy. -func (in *ScoringStrategy) DeepCopy() *ScoringStrategy { - if in == nil { - return nil - } - out := new(ScoringStrategy) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *UtilizationShapePoint) DeepCopyInto(out *UtilizationShapePoint) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UtilizationShapePoint. -func (in *UtilizationShapePoint) DeepCopy() *UtilizationShapePoint { - if in == nil { - return nil - } - out := new(UtilizationShapePoint) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *VolumeBindingArgs) DeepCopyInto(out *VolumeBindingArgs) { - *out = *in - out.TypeMeta = in.TypeMeta - if in.Shape != nil { - in, out := &in.Shape, &out.Shape - *out = make([]UtilizationShapePoint, len(*in)) - copy(*out, *in) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeBindingArgs. -func (in *VolumeBindingArgs) DeepCopy() *VolumeBindingArgs { - if in == nil { - return nil - } - out := new(VolumeBindingArgs) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *VolumeBindingArgs) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go deleted file mode 100644 index 97d540110..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/cache.go +++ /dev/null @@ -1,768 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cache - -import ( - "context" - "errors" - "fmt" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/metrics" -) - -var ( - cleanAssumedPeriod = 1 * time.Second -) - -// New returns a Cache implementation. -// It automatically starts a go routine that manages expiration of assumed pods. -// "ttl" is how long the assumed pod will get expired. -// "ctx" is the context that would close the background goroutine. -func New(ctx context.Context, ttl time.Duration) Cache { - logger := klog.FromContext(ctx) - cache := newCache(ctx, ttl, cleanAssumedPeriod) - cache.run(logger) - return cache -} - -// nodeInfoListItem holds a NodeInfo pointer and acts as an item in a doubly -// linked list. When a NodeInfo is updated, it goes to the head of the list. -// The items closer to the head are the most recently updated items. -type nodeInfoListItem struct { - info *framework.NodeInfo - next *nodeInfoListItem - prev *nodeInfoListItem -} - -type cacheImpl struct { - stop <-chan struct{} - ttl time.Duration - period time.Duration - - // This mutex guards all fields within this cache struct. - mu sync.RWMutex - // a set of assumed pod keys. - // The key could further be used to get an entry in podStates. - assumedPods sets.Set[string] - // a map from pod key to podState. - podStates map[string]*podState - nodes map[string]*nodeInfoListItem - // headNode points to the most recently updated NodeInfo in "nodes". It is the - // head of the linked list. - headNode *nodeInfoListItem - nodeTree *nodeTree - // A map from image name to its ImageStateSummary. - imageStates map[string]*framework.ImageStateSummary -} - -type podState struct { - pod *v1.Pod - // Used by assumedPod to determinate expiration. - // If deadline is nil, assumedPod will never expire. - deadline *time.Time - // Used to block cache from expiring assumedPod if binding still runs - bindingFinished bool -} - -func newCache(ctx context.Context, ttl, period time.Duration) *cacheImpl { - logger := klog.FromContext(ctx) - return &cacheImpl{ - ttl: ttl, - period: period, - stop: ctx.Done(), - - nodes: make(map[string]*nodeInfoListItem), - nodeTree: newNodeTree(logger, nil), - assumedPods: sets.New[string](), - podStates: make(map[string]*podState), - imageStates: make(map[string]*framework.ImageStateSummary), - } -} - -// newNodeInfoListItem initializes a new nodeInfoListItem. -func newNodeInfoListItem(ni *framework.NodeInfo) *nodeInfoListItem { - return &nodeInfoListItem{ - info: ni, - } -} - -// moveNodeInfoToHead moves a NodeInfo to the head of "cache.nodes" doubly -// linked list. The head is the most recently updated NodeInfo. -// We assume cache lock is already acquired. -func (cache *cacheImpl) moveNodeInfoToHead(logger klog.Logger, name string) { - ni, ok := cache.nodes[name] - if !ok { - logger.Error(nil, "No node info with given name found in the cache", "node", klog.KRef("", name)) - return - } - // if the node info list item is already at the head, we are done. - if ni == cache.headNode { - return - } - - if ni.prev != nil { - ni.prev.next = ni.next - } - if ni.next != nil { - ni.next.prev = ni.prev - } - if cache.headNode != nil { - cache.headNode.prev = ni - } - ni.next = cache.headNode - ni.prev = nil - cache.headNode = ni -} - -// removeNodeInfoFromList removes a NodeInfo from the "cache.nodes" doubly -// linked list. -// We assume cache lock is already acquired. -func (cache *cacheImpl) removeNodeInfoFromList(logger klog.Logger, name string) { - ni, ok := cache.nodes[name] - if !ok { - logger.Error(nil, "No node info with given name found in the cache", "node", klog.KRef("", name)) - return - } - - if ni.prev != nil { - ni.prev.next = ni.next - } - if ni.next != nil { - ni.next.prev = ni.prev - } - // if the removed item was at the head, we must update the head. - if ni == cache.headNode { - cache.headNode = ni.next - } - delete(cache.nodes, name) -} - -// Dump produces a dump of the current scheduler cache. This is used for -// debugging purposes only and shouldn't be confused with UpdateSnapshot -// function. -// This method is expensive, and should be only used in non-critical path. -func (cache *cacheImpl) Dump() *Dump { - cache.mu.RLock() - defer cache.mu.RUnlock() - - nodes := make(map[string]*framework.NodeInfo, len(cache.nodes)) - for k, v := range cache.nodes { - nodes[k] = v.info.Snapshot() - } - - return &Dump{ - Nodes: nodes, - AssumedPods: cache.assumedPods.Union(nil), - } -} - -// UpdateSnapshot takes a snapshot of cached NodeInfo map. This is called at -// beginning of every scheduling cycle. -// The snapshot only includes Nodes that are not deleted at the time this function is called. -// nodeInfo.Node() is guaranteed to be not nil for all the nodes in the snapshot. -// This function tracks generation number of NodeInfo and updates only the -// entries of an existing snapshot that have changed after the snapshot was taken. -func (cache *cacheImpl) UpdateSnapshot(logger klog.Logger, nodeSnapshot *Snapshot) error { - cache.mu.Lock() - defer cache.mu.Unlock() - - // Get the last generation of the snapshot. - snapshotGeneration := nodeSnapshot.generation - - // NodeInfoList and HavePodsWithAffinityNodeInfoList must be re-created if a node was added - // or removed from the cache. - updateAllLists := false - // HavePodsWithAffinityNodeInfoList must be re-created if a node changed its - // status from having pods with affinity to NOT having pods with affinity or the other - // way around. - updateNodesHavePodsWithAffinity := false - // HavePodsWithRequiredAntiAffinityNodeInfoList must be re-created if a node changed its - // status from having pods with required anti-affinity to NOT having pods with required - // anti-affinity or the other way around. - updateNodesHavePodsWithRequiredAntiAffinity := false - // usedPVCSet must be re-created whenever the head node generation is greater than - // last snapshot generation. - updateUsedPVCSet := false - - // Start from the head of the NodeInfo doubly linked list and update snapshot - // of NodeInfos updated after the last snapshot. - for node := cache.headNode; node != nil; node = node.next { - if node.info.Generation <= snapshotGeneration { - // all the nodes are updated before the existing snapshot. We are done. - break - } - if np := node.info.Node(); np != nil { - existing, ok := nodeSnapshot.nodeInfoMap[np.Name] - if !ok { - updateAllLists = true - existing = &framework.NodeInfo{} - nodeSnapshot.nodeInfoMap[np.Name] = existing - } - clone := node.info.Snapshot() - // We track nodes that have pods with affinity, here we check if this node changed its - // status from having pods with affinity to NOT having pods with affinity or the other - // way around. - if (len(existing.PodsWithAffinity) > 0) != (len(clone.PodsWithAffinity) > 0) { - updateNodesHavePodsWithAffinity = true - } - if (len(existing.PodsWithRequiredAntiAffinity) > 0) != (len(clone.PodsWithRequiredAntiAffinity) > 0) { - updateNodesHavePodsWithRequiredAntiAffinity = true - } - if !updateUsedPVCSet { - if len(existing.PVCRefCounts) != len(clone.PVCRefCounts) { - updateUsedPVCSet = true - } else { - for pvcKey := range clone.PVCRefCounts { - if _, found := existing.PVCRefCounts[pvcKey]; !found { - updateUsedPVCSet = true - break - } - } - } - } - // We need to preserve the original pointer of the NodeInfo struct since it - // is used in the NodeInfoList, which we may not update. - *existing = *clone - } - } - // Update the snapshot generation with the latest NodeInfo generation. - if cache.headNode != nil { - nodeSnapshot.generation = cache.headNode.info.Generation - } - - // Comparing to pods in nodeTree. - // Deleted nodes get removed from the tree, but they might remain in the nodes map - // if they still have non-deleted Pods. - if len(nodeSnapshot.nodeInfoMap) > cache.nodeTree.numNodes { - cache.removeDeletedNodesFromSnapshot(nodeSnapshot) - updateAllLists = true - } - - if updateAllLists || updateNodesHavePodsWithAffinity || updateNodesHavePodsWithRequiredAntiAffinity || updateUsedPVCSet { - cache.updateNodeInfoSnapshotList(logger, nodeSnapshot, updateAllLists) - } - - if len(nodeSnapshot.nodeInfoList) != cache.nodeTree.numNodes { - errMsg := fmt.Sprintf("snapshot state is not consistent, length of NodeInfoList=%v not equal to length of nodes in tree=%v "+ - ", length of NodeInfoMap=%v, length of nodes in cache=%v"+ - ", trying to recover", - len(nodeSnapshot.nodeInfoList), cache.nodeTree.numNodes, - len(nodeSnapshot.nodeInfoMap), len(cache.nodes)) - logger.Error(nil, errMsg) - // We will try to recover by re-creating the lists for the next scheduling cycle, but still return an - // error to surface the problem, the error will likely cause a failure to the current scheduling cycle. - cache.updateNodeInfoSnapshotList(logger, nodeSnapshot, true) - return errors.New(errMsg) - } - - return nil -} - -func (cache *cacheImpl) updateNodeInfoSnapshotList(logger klog.Logger, snapshot *Snapshot, updateAll bool) { - snapshot.havePodsWithAffinityNodeInfoList = make([]*framework.NodeInfo, 0, cache.nodeTree.numNodes) - snapshot.havePodsWithRequiredAntiAffinityNodeInfoList = make([]*framework.NodeInfo, 0, cache.nodeTree.numNodes) - snapshot.usedPVCSet = sets.New[string]() - if updateAll { - // Take a snapshot of the nodes order in the tree - snapshot.nodeInfoList = make([]*framework.NodeInfo, 0, cache.nodeTree.numNodes) - nodesList, err := cache.nodeTree.list() - if err != nil { - logger.Error(err, "Error occurred while retrieving the list of names of the nodes from node tree") - } - for _, nodeName := range nodesList { - if nodeInfo := snapshot.nodeInfoMap[nodeName]; nodeInfo != nil { - snapshot.nodeInfoList = append(snapshot.nodeInfoList, nodeInfo) - if len(nodeInfo.PodsWithAffinity) > 0 { - snapshot.havePodsWithAffinityNodeInfoList = append(snapshot.havePodsWithAffinityNodeInfoList, nodeInfo) - } - if len(nodeInfo.PodsWithRequiredAntiAffinity) > 0 { - snapshot.havePodsWithRequiredAntiAffinityNodeInfoList = append(snapshot.havePodsWithRequiredAntiAffinityNodeInfoList, nodeInfo) - } - for key := range nodeInfo.PVCRefCounts { - snapshot.usedPVCSet.Insert(key) - } - } else { - logger.Error(nil, "Node exists in nodeTree but not in NodeInfoMap, this should not happen", "node", klog.KRef("", nodeName)) - } - } - } else { - for _, nodeInfo := range snapshot.nodeInfoList { - if len(nodeInfo.PodsWithAffinity) > 0 { - snapshot.havePodsWithAffinityNodeInfoList = append(snapshot.havePodsWithAffinityNodeInfoList, nodeInfo) - } - if len(nodeInfo.PodsWithRequiredAntiAffinity) > 0 { - snapshot.havePodsWithRequiredAntiAffinityNodeInfoList = append(snapshot.havePodsWithRequiredAntiAffinityNodeInfoList, nodeInfo) - } - for key := range nodeInfo.PVCRefCounts { - snapshot.usedPVCSet.Insert(key) - } - } - } -} - -// If certain nodes were deleted after the last snapshot was taken, we should remove them from the snapshot. -func (cache *cacheImpl) removeDeletedNodesFromSnapshot(snapshot *Snapshot) { - toDelete := len(snapshot.nodeInfoMap) - cache.nodeTree.numNodes - for name := range snapshot.nodeInfoMap { - if toDelete <= 0 { - break - } - if n, ok := cache.nodes[name]; !ok || n.info.Node() == nil { - delete(snapshot.nodeInfoMap, name) - toDelete-- - } - } -} - -// NodeCount returns the number of nodes in the cache. -// DO NOT use outside of tests. -func (cache *cacheImpl) NodeCount() int { - cache.mu.RLock() - defer cache.mu.RUnlock() - return len(cache.nodes) -} - -// PodCount returns the number of pods in the cache (including those from deleted nodes). -// DO NOT use outside of tests. -func (cache *cacheImpl) PodCount() (int, error) { - cache.mu.RLock() - defer cache.mu.RUnlock() - // podFilter is expected to return true for most or all of the pods. We - // can avoid expensive array growth without wasting too much memory by - // pre-allocating capacity. - count := 0 - for _, n := range cache.nodes { - count += len(n.info.Pods) - } - return count, nil -} - -func (cache *cacheImpl) AssumePod(logger klog.Logger, pod *v1.Pod) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - - cache.mu.Lock() - defer cache.mu.Unlock() - if _, ok := cache.podStates[key]; ok { - return fmt.Errorf("pod %v(%v) is in the cache, so can't be assumed", key, klog.KObj(pod)) - } - - return cache.addPod(logger, pod, true) -} - -func (cache *cacheImpl) FinishBinding(logger klog.Logger, pod *v1.Pod) error { - return cache.finishBinding(logger, pod, time.Now()) -} - -// finishBinding exists to make tests deterministic by injecting now as an argument -func (cache *cacheImpl) finishBinding(logger klog.Logger, pod *v1.Pod, now time.Time) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - - cache.mu.RLock() - defer cache.mu.RUnlock() - - logger.V(5).Info("Finished binding for pod, can be expired", "podKey", key, "pod", klog.KObj(pod)) - currState, ok := cache.podStates[key] - if ok && cache.assumedPods.Has(key) { - if cache.ttl == time.Duration(0) { - currState.deadline = nil - } else { - dl := now.Add(cache.ttl) - currState.deadline = &dl - } - currState.bindingFinished = true - } - return nil -} - -func (cache *cacheImpl) ForgetPod(logger klog.Logger, pod *v1.Pod) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - - cache.mu.Lock() - defer cache.mu.Unlock() - - currState, ok := cache.podStates[key] - if ok && currState.pod.Spec.NodeName != pod.Spec.NodeName { - return fmt.Errorf("pod %v(%v) was assumed on %v but assigned to %v", key, klog.KObj(pod), pod.Spec.NodeName, currState.pod.Spec.NodeName) - } - - // Only assumed pod can be forgotten. - if ok && cache.assumedPods.Has(key) { - return cache.removePod(logger, pod) - } - return fmt.Errorf("pod %v(%v) wasn't assumed so cannot be forgotten", key, klog.KObj(pod)) -} - -// Assumes that lock is already acquired. -func (cache *cacheImpl) addPod(logger klog.Logger, pod *v1.Pod, assumePod bool) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - n, ok := cache.nodes[pod.Spec.NodeName] - if !ok { - n = newNodeInfoListItem(framework.NewNodeInfo()) - cache.nodes[pod.Spec.NodeName] = n - } - n.info.AddPod(pod) - cache.moveNodeInfoToHead(logger, pod.Spec.NodeName) - ps := &podState{ - pod: pod, - } - cache.podStates[key] = ps - if assumePod { - cache.assumedPods.Insert(key) - } - return nil -} - -// Assumes that lock is already acquired. -func (cache *cacheImpl) updatePod(logger klog.Logger, oldPod, newPod *v1.Pod) error { - if err := cache.removePod(logger, oldPod); err != nil { - return err - } - return cache.addPod(logger, newPod, false) -} - -// Assumes that lock is already acquired. -// Removes a pod from the cached node info. If the node information was already -// removed and there are no more pods left in the node, cleans up the node from -// the cache. -func (cache *cacheImpl) removePod(logger klog.Logger, pod *v1.Pod) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - - n, ok := cache.nodes[pod.Spec.NodeName] - if !ok { - logger.Error(nil, "Node not found when trying to remove pod", "node", klog.KRef("", pod.Spec.NodeName), "podKey", key, "pod", klog.KObj(pod)) - } else { - if err := n.info.RemovePod(logger, pod); err != nil { - return err - } - if len(n.info.Pods) == 0 && n.info.Node() == nil { - cache.removeNodeInfoFromList(logger, pod.Spec.NodeName) - } else { - cache.moveNodeInfoToHead(logger, pod.Spec.NodeName) - } - } - - delete(cache.podStates, key) - delete(cache.assumedPods, key) - return nil -} - -func (cache *cacheImpl) AddPod(logger klog.Logger, pod *v1.Pod) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - - cache.mu.Lock() - defer cache.mu.Unlock() - - currState, ok := cache.podStates[key] - switch { - case ok && cache.assumedPods.Has(key): - // When assuming, we've already added the Pod to cache, - // Just update here to make sure the Pod's status is up-to-date. - if err = cache.updatePod(logger, currState.pod, pod); err != nil { - logger.Error(err, "Error occurred while updating pod") - } - if currState.pod.Spec.NodeName != pod.Spec.NodeName { - // The pod was added to a different node than it was assumed to. - logger.Info("Pod was added to a different node than it was assumed", "podKey", key, "pod", klog.KObj(pod), "assumedNode", klog.KRef("", pod.Spec.NodeName), "currentNode", klog.KRef("", currState.pod.Spec.NodeName)) - return nil - } - case !ok: - // Pod was expired. We should add it back. - if err = cache.addPod(logger, pod, false); err != nil { - logger.Error(err, "Error occurred while adding pod") - } - default: - return fmt.Errorf("pod %v(%v) was already in added state", key, klog.KObj(pod)) - } - return nil -} - -func (cache *cacheImpl) UpdatePod(logger klog.Logger, oldPod, newPod *v1.Pod) error { - key, err := framework.GetPodKey(oldPod) - if err != nil { - return err - } - - cache.mu.Lock() - defer cache.mu.Unlock() - - currState, ok := cache.podStates[key] - if !ok { - return fmt.Errorf("pod %v(%v) is not added to scheduler cache, so cannot be updated", key, klog.KObj(oldPod)) - } - - // An assumed pod won't have Update/Remove event. It needs to have Add event - // before Update event, in which case the state would change from Assumed to Added. - if cache.assumedPods.Has(key) { - return fmt.Errorf("assumed pod %v(%v) should not be updated", key, klog.KObj(oldPod)) - } - - if currState.pod.Spec.NodeName != newPod.Spec.NodeName { - logger.Error(nil, "Pod updated on a different node than previously added to", "podKey", key, "pod", klog.KObj(oldPod)) - logger.Error(nil, "scheduler cache is corrupted and can badly affect scheduling decisions") - klog.FlushAndExit(klog.ExitFlushTimeout, 1) - } - return cache.updatePod(logger, oldPod, newPod) -} - -func (cache *cacheImpl) RemovePod(logger klog.Logger, pod *v1.Pod) error { - key, err := framework.GetPodKey(pod) - if err != nil { - return err - } - - cache.mu.Lock() - defer cache.mu.Unlock() - - currState, ok := cache.podStates[key] - if !ok { - return fmt.Errorf("pod %v(%v) is not found in scheduler cache, so cannot be removed from it", key, klog.KObj(pod)) - } - if currState.pod.Spec.NodeName != pod.Spec.NodeName { - logger.Error(nil, "Pod was added to a different node than it was assumed", "podKey", key, "pod", klog.KObj(pod), "assumedNode", klog.KRef("", pod.Spec.NodeName), "currentNode", klog.KRef("", currState.pod.Spec.NodeName)) - if pod.Spec.NodeName != "" { - // An empty NodeName is possible when the scheduler misses a Delete - // event and it gets the last known state from the informer cache. - logger.Error(nil, "scheduler cache is corrupted and can badly affect scheduling decisions") - klog.FlushAndExit(klog.ExitFlushTimeout, 1) - } - } - return cache.removePod(logger, currState.pod) -} - -func (cache *cacheImpl) IsAssumedPod(pod *v1.Pod) (bool, error) { - key, err := framework.GetPodKey(pod) - if err != nil { - return false, err - } - - cache.mu.RLock() - defer cache.mu.RUnlock() - - return cache.assumedPods.Has(key), nil -} - -// GetPod might return a pod for which its node has already been deleted from -// the main cache. This is useful to properly process pod update events. -func (cache *cacheImpl) GetPod(pod *v1.Pod) (*v1.Pod, error) { - key, err := framework.GetPodKey(pod) - if err != nil { - return nil, err - } - - cache.mu.RLock() - defer cache.mu.RUnlock() - - podState, ok := cache.podStates[key] - if !ok { - return nil, fmt.Errorf("pod %v(%v) does not exist in scheduler cache", key, klog.KObj(pod)) - } - - return podState.pod, nil -} - -func (cache *cacheImpl) AddNode(logger klog.Logger, node *v1.Node) *framework.NodeInfo { - cache.mu.Lock() - defer cache.mu.Unlock() - - n, ok := cache.nodes[node.Name] - if !ok { - n = newNodeInfoListItem(framework.NewNodeInfo()) - cache.nodes[node.Name] = n - } else { - cache.removeNodeImageStates(n.info.Node()) - } - cache.moveNodeInfoToHead(logger, node.Name) - - cache.nodeTree.addNode(logger, node) - cache.addNodeImageStates(node, n.info) - n.info.SetNode(node) - return n.info.Snapshot() -} - -func (cache *cacheImpl) UpdateNode(logger klog.Logger, oldNode, newNode *v1.Node) *framework.NodeInfo { - cache.mu.Lock() - defer cache.mu.Unlock() - n, ok := cache.nodes[newNode.Name] - if !ok { - n = newNodeInfoListItem(framework.NewNodeInfo()) - cache.nodes[newNode.Name] = n - cache.nodeTree.addNode(logger, newNode) - } else { - cache.removeNodeImageStates(n.info.Node()) - } - cache.moveNodeInfoToHead(logger, newNode.Name) - - cache.nodeTree.updateNode(logger, oldNode, newNode) - cache.addNodeImageStates(newNode, n.info) - n.info.SetNode(newNode) - return n.info.Snapshot() -} - -// RemoveNode removes a node from the cache's tree. -// The node might still have pods because their deletion events didn't arrive -// yet. Those pods are considered removed from the cache, being the node tree -// the source of truth. -// However, we keep a ghost node with the list of pods until all pod deletion -// events have arrived. A ghost node is skipped from snapshots. -func (cache *cacheImpl) RemoveNode(logger klog.Logger, node *v1.Node) error { - cache.mu.Lock() - defer cache.mu.Unlock() - - n, ok := cache.nodes[node.Name] - if !ok { - return fmt.Errorf("node %v is not found", node.Name) - } - n.info.RemoveNode() - // We remove NodeInfo for this node only if there aren't any pods on this node. - // We can't do it unconditionally, because notifications about pods are delivered - // in a different watch, and thus can potentially be observed later, even though - // they happened before node removal. - if len(n.info.Pods) == 0 { - cache.removeNodeInfoFromList(logger, node.Name) - } else { - cache.moveNodeInfoToHead(logger, node.Name) - } - if err := cache.nodeTree.removeNode(logger, node); err != nil { - return err - } - cache.removeNodeImageStates(node) - return nil -} - -// addNodeImageStates adds states of the images on given node to the given nodeInfo and update the imageStates in -// scheduler cache. This function assumes the lock to scheduler cache has been acquired. -func (cache *cacheImpl) addNodeImageStates(node *v1.Node, nodeInfo *framework.NodeInfo) { - newSum := make(map[string]*framework.ImageStateSummary) - - for _, image := range node.Status.Images { - for _, name := range image.Names { - // update the entry in imageStates - state, ok := cache.imageStates[name] - if !ok { - state = &framework.ImageStateSummary{ - Size: image.SizeBytes, - Nodes: sets.New(node.Name), - } - cache.imageStates[name] = state - } else { - state.Nodes.Insert(node.Name) - } - // create the ImageStateSummary for this image - if _, ok := newSum[name]; !ok { - newSum[name] = state - } - } - } - nodeInfo.ImageStates = newSum -} - -// removeNodeImageStates removes the given node record from image entries having the node -// in imageStates cache. After the removal, if any image becomes free, i.e., the image -// is no longer available on any node, the image entry will be removed from imageStates. -func (cache *cacheImpl) removeNodeImageStates(node *v1.Node) { - if node == nil { - return - } - - for _, image := range node.Status.Images { - for _, name := range image.Names { - state, ok := cache.imageStates[name] - if ok { - state.Nodes.Delete(node.Name) - if state.Nodes.Len() == 0 { - // Remove the unused image to make sure the length of - // imageStates represents the total number of different - // images on all nodes - delete(cache.imageStates, name) - } - } - } - } -} - -func (cache *cacheImpl) run(logger klog.Logger) { - go wait.Until(func() { - cache.cleanupAssumedPods(logger, time.Now()) - }, cache.period, cache.stop) -} - -// cleanupAssumedPods exists for making test deterministic by taking time as input argument. -// It also reports metrics on the cache size for nodes, pods, and assumed pods. -func (cache *cacheImpl) cleanupAssumedPods(logger klog.Logger, now time.Time) { - cache.mu.Lock() - defer cache.mu.Unlock() - defer cache.updateMetrics() - - // The size of assumedPods should be small - for key := range cache.assumedPods { - ps, ok := cache.podStates[key] - if !ok { - logger.Error(nil, "Key found in assumed set but not in podStates, potentially a logical error") - klog.FlushAndExit(klog.ExitFlushTimeout, 1) - } - if !ps.bindingFinished { - logger.V(5).Info("Could not expire cache for pod as binding is still in progress", "podKey", key, "pod", klog.KObj(ps.pod)) - continue - } - if cache.ttl != 0 && now.After(*ps.deadline) { - logger.Info("Pod expired", "podKey", key, "pod", klog.KObj(ps.pod)) - if err := cache.removePod(logger, ps.pod); err != nil { - logger.Error(err, "ExpirePod failed", "podKey", key, "pod", klog.KObj(ps.pod)) - } - } - } -} - -// updateMetrics updates cache size metric values for pods, assumed pods, and nodes -func (cache *cacheImpl) updateMetrics() { - metrics.CacheSize.WithLabelValues("assumed_pods").Set(float64(len(cache.assumedPods))) - metrics.CacheSize.WithLabelValues("pods").Set(float64(len(cache.podStates))) - metrics.CacheSize.WithLabelValues("nodes").Set(float64(len(cache.nodes))) - - // we intentionally keep them with the deprecation and will remove at v1.34. - //nolint:staticcheck - metrics.SchedulerCacheSize.WithLabelValues("assumed_pods").Set(float64(len(cache.assumedPods))) - //nolint:staticcheck - metrics.SchedulerCacheSize.WithLabelValues("pods").Set(float64(len(cache.podStates))) - //nolint:staticcheck - metrics.SchedulerCacheSize.WithLabelValues("nodes").Set(float64(len(cache.nodes))) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/comparer.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/comparer.go deleted file mode 100644 index cbba8865d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/comparer.go +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package debugger - -import ( - "sort" - "strings" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - corelisters "k8s.io/client-go/listers/core/v1" - "k8s.io/klog/v2" - internalcache "k8s.io/kubernetes/pkg/scheduler/backend/cache" - internalqueue "k8s.io/kubernetes/pkg/scheduler/backend/queue" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// CacheComparer is an implementation of the Scheduler's cache comparer. -type CacheComparer struct { - NodeLister corelisters.NodeLister - PodLister corelisters.PodLister - Cache internalcache.Cache - PodQueue internalqueue.SchedulingQueue -} - -// Compare compares the nodes and pods of NodeLister with Cache.Snapshot. -func (c *CacheComparer) Compare(logger klog.Logger) error { - logger.V(3).Info("Cache comparer started") - defer logger.V(3).Info("Cache comparer finished") - - nodes, err := c.NodeLister.List(labels.Everything()) - if err != nil { - return err - } - - pods, err := c.PodLister.List(labels.Everything()) - if err != nil { - return err - } - - dump := c.Cache.Dump() - - pendingPods, _ := c.PodQueue.PendingPods() - - if missed, redundant := c.CompareNodes(nodes, dump.Nodes); len(missed)+len(redundant) != 0 { - logger.Info("Cache mismatch", "missedNodes", missed, "redundantNodes", redundant) - } - - if missed, redundant := c.ComparePods(pods, pendingPods, dump.Nodes); len(missed)+len(redundant) != 0 { - logger.Info("Cache mismatch", "missedPods", missed, "redundantPods", redundant) - } - - return nil -} - -// CompareNodes compares actual nodes with cached nodes. -func (c *CacheComparer) CompareNodes(nodes []*v1.Node, nodeinfos map[string]*framework.NodeInfo) (missed, redundant []string) { - actual := []string{} - for _, node := range nodes { - actual = append(actual, node.Name) - } - - cached := []string{} - for nodeName := range nodeinfos { - cached = append(cached, nodeName) - } - - return compareStrings(actual, cached) -} - -// ComparePods compares actual pods with cached pods. -func (c *CacheComparer) ComparePods(pods, waitingPods []*v1.Pod, nodeinfos map[string]*framework.NodeInfo) (missed, redundant []string) { - actual := []string{} - for _, pod := range pods { - actual = append(actual, string(pod.UID)) - } - - cached := []string{} - for _, nodeinfo := range nodeinfos { - for _, p := range nodeinfo.Pods { - cached = append(cached, string(p.Pod.UID)) - } - } - for _, pod := range waitingPods { - cached = append(cached, string(pod.UID)) - } - - return compareStrings(actual, cached) -} - -func compareStrings(actual, cached []string) (missed, redundant []string) { - missed, redundant = []string{}, []string{} - - sort.Strings(actual) - sort.Strings(cached) - - compare := func(i, j int) int { - if i == len(actual) { - return 1 - } else if j == len(cached) { - return -1 - } - return strings.Compare(actual[i], cached[j]) - } - - for i, j := 0, 0; i < len(actual) || j < len(cached); { - switch compare(i, j) { - case 0: - i++ - j++ - case -1: - missed = append(missed, actual[i]) - i++ - case 1: - redundant = append(redundant, cached[j]) - j++ - } - } - - return -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/debugger.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/debugger.go deleted file mode 100644 index 5f0bc8a2c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/debugger.go +++ /dev/null @@ -1,76 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package debugger - -import ( - "context" - "os" - "os/signal" - - corelisters "k8s.io/client-go/listers/core/v1" - "k8s.io/klog/v2" - internalcache "k8s.io/kubernetes/pkg/scheduler/backend/cache" - internalqueue "k8s.io/kubernetes/pkg/scheduler/backend/queue" -) - -// CacheDebugger provides ways to check and write cache information for debugging. -type CacheDebugger struct { - Comparer CacheComparer - Dumper CacheDumper -} - -// New creates a CacheDebugger. -func New( - nodeLister corelisters.NodeLister, - podLister corelisters.PodLister, - cache internalcache.Cache, - podQueue internalqueue.SchedulingQueue, -) *CacheDebugger { - return &CacheDebugger{ - Comparer: CacheComparer{ - NodeLister: nodeLister, - PodLister: podLister, - Cache: cache, - PodQueue: podQueue, - }, - Dumper: CacheDumper{ - cache: cache, - podQueue: podQueue, - }, - } -} - -// ListenForSignal starts a goroutine that will trigger the CacheDebugger's -// behavior when the process receives SIGINT (Windows) or SIGUSER2 (non-Windows). -func (d *CacheDebugger) ListenForSignal(ctx context.Context) { - logger := klog.FromContext(ctx) - stopCh := ctx.Done() - ch := make(chan os.Signal, 1) - signal.Notify(ch, compareSignal) - - go func() { - for { - select { - case <-stopCh: - return - case <-ch: - d.Comparer.Compare(logger) - d.Dumper.DumpAll(logger) - } - } - }() -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/dumper.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/dumper.go deleted file mode 100644 index 96288a501..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/dumper.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package debugger - -import ( - "fmt" - "strings" - - "k8s.io/klog/v2" - - v1 "k8s.io/api/core/v1" - internalcache "k8s.io/kubernetes/pkg/scheduler/backend/cache" - "k8s.io/kubernetes/pkg/scheduler/backend/queue" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// CacheDumper writes some information from the scheduler cache and the scheduling queue to the -// scheduler logs for debugging purposes. -type CacheDumper struct { - cache internalcache.Cache - podQueue queue.SchedulingQueue -} - -// DumpAll writes cached nodes and scheduling queue information to the scheduler logs. -func (d *CacheDumper) DumpAll(logger klog.Logger) { - d.dumpNodes(logger) - d.dumpSchedulingQueue(logger) -} - -// dumpNodes writes NodeInfo to the scheduler logs. -func (d *CacheDumper) dumpNodes(logger klog.Logger) { - dump := d.cache.Dump() - nodeInfos := make([]string, 0, len(dump.Nodes)) - for name, nodeInfo := range dump.Nodes { - nodeInfos = append(nodeInfos, d.printNodeInfo(name, nodeInfo)) - } - // Extra blank line added between node entries for readability. - logger.Info("Dump of cached NodeInfo", "nodes", strings.Join(nodeInfos, "\n\n")) -} - -// dumpSchedulingQueue writes pods in the scheduling queue to the scheduler logs. -func (d *CacheDumper) dumpSchedulingQueue(logger klog.Logger) { - pendingPods, s := d.podQueue.PendingPods() - var podData strings.Builder - for _, p := range pendingPods { - podData.WriteString(printPod(p)) - } - logger.Info("Dump of scheduling queue", "summary", s, "pods", podData.String()) -} - -// printNodeInfo writes parts of NodeInfo to a string. -func (d *CacheDumper) printNodeInfo(name string, n *framework.NodeInfo) string { - var nodeData strings.Builder - nodeData.WriteString(fmt.Sprintf("Node name: %s\nDeleted: %t\nRequested Resources: %+v\nAllocatable Resources:%+v\nScheduled Pods(number: %v):\n", - name, n.Node() == nil, n.Requested, n.Allocatable, len(n.Pods))) - // Dumping Pod Info - for _, p := range n.Pods { - nodeData.WriteString(printPod(p.Pod)) - } - // Dumping nominated pods info on the node - nominatedPodInfos := d.podQueue.NominatedPodsForNode(name) - if len(nominatedPodInfos) != 0 { - nodeData.WriteString(fmt.Sprintf("Nominated Pods(number: %v):\n", len(nominatedPodInfos))) - for _, pi := range nominatedPodInfos { - nodeData.WriteString(printPod(pi.Pod)) - } - } - return nodeData.String() -} - -// printPod writes parts of a Pod object to a string. -func printPod(p *v1.Pod) string { - return fmt.Sprintf("name: %v, namespace: %v, uid: %v, phase: %v, nominated node: %v\n", p.Name, p.Namespace, p.UID, p.Status.Phase, p.Status.NominatedNodeName) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go deleted file mode 100644 index df5c83cea..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal.go +++ /dev/null @@ -1,26 +0,0 @@ -//go:build !windows -// +build !windows - -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package debugger - -import "syscall" - -// compareSignal is the signal to trigger cache compare. For non-windows -// environment it's SIGUSR2. -var compareSignal = syscall.SIGUSR2 diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal_windows.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal_windows.go deleted file mode 100644 index 25c015b0e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger/signal_windows.go +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package debugger - -import "os" - -// compareSignal is the signal to trigger cache compare. For windows, -// it's SIGINT. -var compareSignal = os.Interrupt diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go deleted file mode 100644 index 24b7fd490..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/interface.go +++ /dev/null @@ -1,123 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cache - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// Cache collects pods' information and provides node-level aggregated information. -// It's intended for generic scheduler to do efficient lookup. -// Cache's operations are pod centric. It does incremental updates based on pod events. -// Pod events are sent via network. We don't have guaranteed delivery of all events: -// We use Reflector to list and watch from remote. -// Reflector might be slow and do a relist, which would lead to missing events. -// -// State Machine of a pod's events in scheduler's cache: -// -// +-------------------------------------------+ +----+ -// | Add | | | -// | | | | Update -// + Assume Add v v | -// -// Initial +--------> Assumed +------------+---> Added <--+ -// -// ^ + + | + -// | | | | | -// | | | Add | | Remove -// | | | | | -// | | | + | -// +----------------+ +-----------> Expired +----> Deleted -// Forget Expire -// -// Note that an assumed pod can expire, because if we haven't received Add event notifying us -// for a while, there might be some problems and we shouldn't keep the pod in cache anymore. -// -// Note that "Initial", "Expired", and "Deleted" pods do not actually exist in cache. -// Based on existing use cases, we are making the following assumptions: -// - No pod would be assumed twice -// - A pod could be added without going through scheduler. In this case, we will see Add but not Assume event. -// - If a pod wasn't added, it wouldn't be removed or updated. -// - Both "Expired" and "Deleted" are valid end states. In case of some problems, e.g. network issue, -// a pod might have changed its state (e.g. added and deleted) without delivering notification to the cache. -type Cache interface { - // NodeCount returns the number of nodes in the cache. - // DO NOT use outside of tests. - NodeCount() int - - // PodCount returns the number of pods in the cache (including those from deleted nodes). - // DO NOT use outside of tests. - PodCount() (int, error) - - // AssumePod assumes a pod scheduled and aggregates the pod's information into its node. - // The implementation also decides the policy to expire pod before being confirmed (receiving Add event). - // After expiration, its information would be subtracted. - AssumePod(logger klog.Logger, pod *v1.Pod) error - - // FinishBinding signals that cache for assumed pod can be expired - FinishBinding(logger klog.Logger, pod *v1.Pod) error - - // ForgetPod removes an assumed pod from cache. - ForgetPod(logger klog.Logger, pod *v1.Pod) error - - // AddPod either confirms a pod if it's assumed, or adds it back if it's expired. - // If added back, the pod's information would be added again. - AddPod(logger klog.Logger, pod *v1.Pod) error - - // UpdatePod removes oldPod's information and adds newPod's information. - UpdatePod(logger klog.Logger, oldPod, newPod *v1.Pod) error - - // RemovePod removes a pod. The pod's information would be subtracted from assigned node. - RemovePod(logger klog.Logger, pod *v1.Pod) error - - // GetPod returns the pod from the cache with the same namespace and the - // same name of the specified pod. - GetPod(pod *v1.Pod) (*v1.Pod, error) - - // IsAssumedPod returns true if the pod is assumed and not expired. - IsAssumedPod(pod *v1.Pod) (bool, error) - - // AddNode adds overall information about node. - // It returns a clone of added NodeInfo object. - AddNode(logger klog.Logger, node *v1.Node) *framework.NodeInfo - - // UpdateNode updates overall information about node. - // It returns a clone of updated NodeInfo object. - UpdateNode(logger klog.Logger, oldNode, newNode *v1.Node) *framework.NodeInfo - - // RemoveNode removes overall information about node. - RemoveNode(logger klog.Logger, node *v1.Node) error - - // UpdateSnapshot updates the passed infoSnapshot to the current contents of Cache. - // The node info contains aggregated information of pods scheduled (including assumed to be) - // on this node. - // The snapshot only includes Nodes that are not deleted at the time this function is called. - // nodeinfo.Node() is guaranteed to be not nil for all the nodes in the snapshot. - UpdateSnapshot(logger klog.Logger, nodeSnapshot *Snapshot) error - - // Dump produces a dump of the current cache. - Dump() *Dump -} - -// Dump is a dump of the cache state. -type Dump struct { - AssumedPods sets.Set[string] - Nodes map[string]*framework.NodeInfo -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/node_tree.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/node_tree.go deleted file mode 100644 index fe66ea7b2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/node_tree.go +++ /dev/null @@ -1,143 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cache - -import ( - "errors" - "fmt" - - v1 "k8s.io/api/core/v1" - utilnode "k8s.io/component-helpers/node/topology" - "k8s.io/klog/v2" -) - -// nodeTree is a tree-like data structure that holds node names in each zone. Zone names are -// keys to "NodeTree.tree" and values of "NodeTree.tree" are arrays of node names. -// NodeTree is NOT thread-safe, any concurrent updates/reads from it must be synchronized by the caller. -// It is used only by schedulerCache, and should stay as such. -type nodeTree struct { - tree map[string][]string // a map from zone (region-zone) to an array of nodes in the zone. - zones []string // a list of all the zones in the tree (keys) - numNodes int -} - -// newNodeTree creates a NodeTree from nodes. -func newNodeTree(logger klog.Logger, nodes []*v1.Node) *nodeTree { - nt := &nodeTree{ - tree: make(map[string][]string, len(nodes)), - } - for _, n := range nodes { - nt.addNode(logger, n) - } - return nt -} - -// addNode adds a node and its corresponding zone to the tree. If the zone already exists, the node -// is added to the array of nodes in that zone. -func (nt *nodeTree) addNode(logger klog.Logger, n *v1.Node) { - zone := utilnode.GetZoneKey(n) - if na, ok := nt.tree[zone]; ok { - for _, nodeName := range na { - if nodeName == n.Name { - logger.Info("Did not add to the NodeTree because it already exists", "node", klog.KObj(n)) - return - } - } - nt.tree[zone] = append(na, n.Name) - } else { - nt.zones = append(nt.zones, zone) - nt.tree[zone] = []string{n.Name} - } - logger.V(2).Info("Added node to NodeTree", "node", klog.KObj(n), "zone", zone) - nt.numNodes++ -} - -// removeNode removes a node from the NodeTree. -func (nt *nodeTree) removeNode(logger klog.Logger, n *v1.Node) error { - zone := utilnode.GetZoneKey(n) - if na, ok := nt.tree[zone]; ok { - for i, nodeName := range na { - if nodeName == n.Name { - nt.tree[zone] = append(na[:i], na[i+1:]...) - if len(nt.tree[zone]) == 0 { - nt.removeZone(zone) - } - logger.V(2).Info("Removed node from NodeTree", "node", klog.KObj(n), "zone", zone) - nt.numNodes-- - return nil - } - } - } - logger.Error(nil, "Did not remove Node in NodeTree because it was not found", "node", klog.KObj(n), "zone", zone) - return fmt.Errorf("node %q in group %q was not found", n.Name, zone) -} - -// removeZone removes a zone from tree. -// This function must be called while writer locks are hold. -func (nt *nodeTree) removeZone(zone string) { - delete(nt.tree, zone) - for i, z := range nt.zones { - if z == zone { - nt.zones = append(nt.zones[:i], nt.zones[i+1:]...) - return - } - } -} - -// updateNode updates a node in the NodeTree. -func (nt *nodeTree) updateNode(logger klog.Logger, old, new *v1.Node) { - var oldZone string - if old != nil { - oldZone = utilnode.GetZoneKey(old) - } - newZone := utilnode.GetZoneKey(new) - // If the zone ID of the node has not changed, we don't need to do anything. Name of the node - // cannot be changed in an update. - if oldZone == newZone { - return - } - nt.removeNode(logger, old) // No error checking. We ignore whether the old node exists or not. - nt.addNode(logger, new) -} - -// list returns the list of names of the node. NodeTree iterates over zones and in each zone iterates -// over nodes in a round robin fashion. -func (nt *nodeTree) list() ([]string, error) { - if len(nt.zones) == 0 { - return nil, nil - } - nodesList := make([]string, 0, nt.numNodes) - numExhaustedZones := 0 - nodeIndex := 0 - for len(nodesList) < nt.numNodes { - if numExhaustedZones >= len(nt.zones) { // all zones are exhausted. - return nodesList, errors.New("all zones exhausted before reaching count of nodes expected") - } - for zoneIndex := 0; zoneIndex < len(nt.zones); zoneIndex++ { - na := nt.tree[nt.zones[zoneIndex]] - if nodeIndex >= len(na) { // If the zone is exhausted, continue - if nodeIndex == len(na) { // If it is the first time the zone is exhausted - numExhaustedZones++ - } - continue - } - nodesList = append(nodesList, na[nodeIndex]) - } - nodeIndex++ - } - return nodesList, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go deleted file mode 100644 index 164f1510c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/cache/snapshot.go +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package cache - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// Snapshot is a snapshot of cache NodeInfo and NodeTree order. The scheduler takes a -// snapshot at the beginning of each scheduling cycle and uses it for its operations in that cycle. -type Snapshot struct { - // nodeInfoMap a map of node name to a snapshot of its NodeInfo. - nodeInfoMap map[string]*framework.NodeInfo - // nodeInfoList is the list of nodes as ordered in the cache's nodeTree. - nodeInfoList []*framework.NodeInfo - // havePodsWithAffinityNodeInfoList is the list of nodes with at least one pod declaring affinity terms. - havePodsWithAffinityNodeInfoList []*framework.NodeInfo - // havePodsWithRequiredAntiAffinityNodeInfoList is the list of nodes with at least one pod declaring - // required anti-affinity terms. - havePodsWithRequiredAntiAffinityNodeInfoList []*framework.NodeInfo - // usedPVCSet contains a set of PVC names that have one or more scheduled pods using them, - // keyed in the format "namespace/name". - usedPVCSet sets.Set[string] - generation int64 -} - -var _ framework.SharedLister = &Snapshot{} - -// NewEmptySnapshot initializes a Snapshot struct and returns it. -func NewEmptySnapshot() *Snapshot { - return &Snapshot{ - nodeInfoMap: make(map[string]*framework.NodeInfo), - usedPVCSet: sets.New[string](), - } -} - -// NewSnapshot initializes a Snapshot struct and returns it. -func NewSnapshot(pods []*v1.Pod, nodes []*v1.Node) *Snapshot { - nodeInfoMap := createNodeInfoMap(pods, nodes) - nodeInfoList := make([]*framework.NodeInfo, 0, len(nodeInfoMap)) - havePodsWithAffinityNodeInfoList := make([]*framework.NodeInfo, 0, len(nodeInfoMap)) - havePodsWithRequiredAntiAffinityNodeInfoList := make([]*framework.NodeInfo, 0, len(nodeInfoMap)) - for _, v := range nodeInfoMap { - nodeInfoList = append(nodeInfoList, v) - if len(v.PodsWithAffinity) > 0 { - havePodsWithAffinityNodeInfoList = append(havePodsWithAffinityNodeInfoList, v) - } - if len(v.PodsWithRequiredAntiAffinity) > 0 { - havePodsWithRequiredAntiAffinityNodeInfoList = append(havePodsWithRequiredAntiAffinityNodeInfoList, v) - } - } - - s := NewEmptySnapshot() - s.nodeInfoMap = nodeInfoMap - s.nodeInfoList = nodeInfoList - s.havePodsWithAffinityNodeInfoList = havePodsWithAffinityNodeInfoList - s.havePodsWithRequiredAntiAffinityNodeInfoList = havePodsWithRequiredAntiAffinityNodeInfoList - s.usedPVCSet = createUsedPVCSet(pods) - - return s -} - -// createNodeInfoMap obtains a list of pods and pivots that list into a map -// where the keys are node names and the values are the aggregated information -// for that node. -func createNodeInfoMap(pods []*v1.Pod, nodes []*v1.Node) map[string]*framework.NodeInfo { - nodeNameToInfo := make(map[string]*framework.NodeInfo) - for _, pod := range pods { - nodeName := pod.Spec.NodeName - if _, ok := nodeNameToInfo[nodeName]; !ok { - nodeNameToInfo[nodeName] = framework.NewNodeInfo() - } - nodeNameToInfo[nodeName].AddPod(pod) - } - imageExistenceMap := createImageExistenceMap(nodes) - - for _, node := range nodes { - if _, ok := nodeNameToInfo[node.Name]; !ok { - nodeNameToInfo[node.Name] = framework.NewNodeInfo() - } - nodeInfo := nodeNameToInfo[node.Name] - nodeInfo.SetNode(node) - nodeInfo.ImageStates = getNodeImageStates(node, imageExistenceMap) - } - return nodeNameToInfo -} - -func createUsedPVCSet(pods []*v1.Pod) sets.Set[string] { - usedPVCSet := sets.New[string]() - for _, pod := range pods { - if pod.Spec.NodeName == "" { - continue - } - - for _, v := range pod.Spec.Volumes { - if v.PersistentVolumeClaim == nil { - continue - } - - key := framework.GetNamespacedName(pod.Namespace, v.PersistentVolumeClaim.ClaimName) - usedPVCSet.Insert(key) - } - } - return usedPVCSet -} - -// getNodeImageStates returns the given node's image states based on the given imageExistence map. -func getNodeImageStates(node *v1.Node, imageExistenceMap map[string]sets.Set[string]) map[string]*framework.ImageStateSummary { - imageStates := make(map[string]*framework.ImageStateSummary) - - for _, image := range node.Status.Images { - for _, name := range image.Names { - imageStates[name] = &framework.ImageStateSummary{ - Size: image.SizeBytes, - NumNodes: imageExistenceMap[name].Len(), - } - } - } - return imageStates -} - -// createImageExistenceMap returns a map recording on which nodes the images exist, keyed by the images' names. -func createImageExistenceMap(nodes []*v1.Node) map[string]sets.Set[string] { - imageExistenceMap := make(map[string]sets.Set[string]) - for _, node := range nodes { - for _, image := range node.Status.Images { - for _, name := range image.Names { - if _, ok := imageExistenceMap[name]; !ok { - imageExistenceMap[name] = sets.New(node.Name) - } else { - imageExistenceMap[name].Insert(node.Name) - } - } - } - } - return imageExistenceMap -} - -// NodeInfos returns a NodeInfoLister. -func (s *Snapshot) NodeInfos() framework.NodeInfoLister { - return s -} - -// StorageInfos returns a StorageInfoLister. -func (s *Snapshot) StorageInfos() framework.StorageInfoLister { - return s -} - -// NumNodes returns the number of nodes in the snapshot. -func (s *Snapshot) NumNodes() int { - return len(s.nodeInfoList) -} - -// List returns the list of nodes in the snapshot. -func (s *Snapshot) List() ([]*framework.NodeInfo, error) { - return s.nodeInfoList, nil -} - -// HavePodsWithAffinityList returns the list of nodes with at least one pod with inter-pod affinity -func (s *Snapshot) HavePodsWithAffinityList() ([]*framework.NodeInfo, error) { - return s.havePodsWithAffinityNodeInfoList, nil -} - -// HavePodsWithRequiredAntiAffinityList returns the list of nodes with at least one pod with -// required inter-pod anti-affinity -func (s *Snapshot) HavePodsWithRequiredAntiAffinityList() ([]*framework.NodeInfo, error) { - return s.havePodsWithRequiredAntiAffinityNodeInfoList, nil -} - -// Get returns the NodeInfo of the given node name. -func (s *Snapshot) Get(nodeName string) (*framework.NodeInfo, error) { - if v, ok := s.nodeInfoMap[nodeName]; ok && v.Node() != nil { - return v, nil - } - return nil, fmt.Errorf("nodeinfo not found for node name %q", nodeName) -} - -func (s *Snapshot) IsPVCUsedByPods(key string) bool { - return s.usedPVCSet.Has(key) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/heap/heap.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/heap/heap.go deleted file mode 100644 index 182954e23..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/heap/heap.go +++ /dev/null @@ -1,244 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Below is the implementation of the a heap. The logic is pretty much the same -// as cache.heap, however, this heap does not perform synchronization. It leaves -// synchronization to the SchedulingQueue. - -package heap - -import ( - "container/heap" - "fmt" - - "k8s.io/kubernetes/pkg/scheduler/metrics" -) - -// KeyFunc is a function type to get the key from an object. -type KeyFunc[T any] func(obj T) string - -type heapItem[T any] struct { - obj T // The object which is stored in the heap. - index int // The index of the object's key in the Heap.queue. -} - -type itemKeyValue[T any] struct { - key string - obj T -} - -// data is an internal struct that implements the standard heap interface -// and keeps the data stored in the heap. -type data[T any] struct { - // items is a map from key of the objects to the objects and their index. - // We depend on the property that items in the map are in the queue and vice versa. - items map[string]*heapItem[T] - // queue implements a heap data structure and keeps the order of elements - // according to the heap invariant. The queue keeps the keys of objects stored - // in "items". - queue []string - - // keyFunc is used to make the key used for queued item insertion and retrieval, and - // should be deterministic. - keyFunc KeyFunc[T] - // lessFunc is used to compare two objects in the heap. - lessFunc LessFunc[T] -} - -var ( - _ = heap.Interface(&data[any]{}) // heapData is a standard heap -) - -// Less compares two objects and returns true if the first one should go -// in front of the second one in the heap. -func (h *data[T]) Less(i, j int) bool { - if i > len(h.queue) || j > len(h.queue) { - return false - } - itemi, ok := h.items[h.queue[i]] - if !ok { - return false - } - itemj, ok := h.items[h.queue[j]] - if !ok { - return false - } - return h.lessFunc(itemi.obj, itemj.obj) -} - -// Len returns the number of items in the Heap. -func (h *data[T]) Len() int { return len(h.queue) } - -// Swap implements swapping of two elements in the heap. This is a part of standard -// heap interface and should never be called directly. -func (h *data[T]) Swap(i, j int) { - if i < 0 || j < 0 { - return - } - h.queue[i], h.queue[j] = h.queue[j], h.queue[i] - item := h.items[h.queue[i]] - item.index = i - item = h.items[h.queue[j]] - item.index = j -} - -// Push is supposed to be called by container/heap.Push only. -func (h *data[T]) Push(kv interface{}) { - keyValue := kv.(*itemKeyValue[T]) - n := len(h.queue) - h.items[keyValue.key] = &heapItem[T]{keyValue.obj, n} - h.queue = append(h.queue, keyValue.key) -} - -// Pop is supposed to be called by container/heap.Pop only. -func (h *data[T]) Pop() interface{} { - if len(h.queue) == 0 { - return nil - } - key := h.queue[len(h.queue)-1] - h.queue = h.queue[0 : len(h.queue)-1] - item, ok := h.items[key] - if !ok { - // This is an error - return nil - } - delete(h.items, key) - return item.obj -} - -// Peek returns the head of the heap without removing it. -func (h *data[T]) Peek() (T, bool) { - if len(h.queue) > 0 { - return h.items[h.queue[0]].obj, true - } - var zero T - return zero, false -} - -// Heap is a producer/consumer queue that implements a heap data structure. -// It can be used to implement priority queues and similar data structures. -type Heap[T any] struct { - // data stores objects and has a queue that keeps their ordering according - // to the heap invariant. - data *data[T] - // metricRecorder updates the counter when elements of a heap get added or - // removed, and it does nothing if it's nil - metricRecorder metrics.MetricRecorder -} - -// AddOrUpdate inserts an item, and puts it in the queue. The item is updated if it -// already exists. -func (h *Heap[T]) AddOrUpdate(obj T) { - key := h.data.keyFunc(obj) - if _, exists := h.data.items[key]; exists { - h.data.items[key].obj = obj - heap.Fix(h.data, h.data.items[key].index) - } else { - heap.Push(h.data, &itemKeyValue[T]{key, obj}) - if h.metricRecorder != nil { - h.metricRecorder.Inc() - } - } -} - -// Delete removes an item. -func (h *Heap[T]) Delete(obj T) error { - key := h.data.keyFunc(obj) - if item, ok := h.data.items[key]; ok { - heap.Remove(h.data, item.index) - if h.metricRecorder != nil { - h.metricRecorder.Dec() - } - return nil - } - return fmt.Errorf("object not found") -} - -// Peek returns the head of the heap without removing it. -func (h *Heap[T]) Peek() (T, bool) { - return h.data.Peek() -} - -// Pop returns the head of the heap and removes it. -func (h *Heap[T]) Pop() (T, error) { - obj := heap.Pop(h.data) - if obj != nil { - if h.metricRecorder != nil { - h.metricRecorder.Dec() - } - return obj.(T), nil - } - var zero T - return zero, fmt.Errorf("heap is empty") -} - -// Get returns the requested item, or sets exists=false. -func (h *Heap[T]) Get(obj T) (T, bool) { - key := h.data.keyFunc(obj) - return h.GetByKey(key) -} - -// GetByKey returns the requested item, or sets exists=false. -func (h *Heap[T]) GetByKey(key string) (T, bool) { - item, exists := h.data.items[key] - if !exists { - var zero T - return zero, false - } - return item.obj, true -} - -func (h *Heap[T]) Has(obj T) bool { - key := h.data.keyFunc(obj) - _, ok := h.GetByKey(key) - return ok -} - -// List returns a list of all the items. -func (h *Heap[T]) List() []T { - list := make([]T, 0, len(h.data.items)) - for _, item := range h.data.items { - list = append(list, item.obj) - } - return list -} - -// Len returns the number of items in the heap. -func (h *Heap[T]) Len() int { - return len(h.data.queue) -} - -// New returns a Heap which can be used to queue up items to process. -func New[T any](keyFn KeyFunc[T], lessFn LessFunc[T]) *Heap[T] { - return NewWithRecorder(keyFn, lessFn, nil) -} - -// NewWithRecorder wraps an optional metricRecorder to compose a Heap object. -func NewWithRecorder[T any](keyFn KeyFunc[T], lessFn LessFunc[T], metricRecorder metrics.MetricRecorder) *Heap[T] { - return &Heap[T]{ - data: &data[T]{ - items: map[string]*heapItem[T]{}, - queue: []string{}, - keyFunc: keyFn, - lessFunc: lessFn, - }, - metricRecorder: metricRecorder, - } -} - -// LessFunc is a function that receives two items and returns true if the first -// item should be placed before the second one when the list is sorted. -type LessFunc[T any] func(item1, item2 T) bool diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go deleted file mode 100644 index 14c734d75..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/active_queue.go +++ /dev/null @@ -1,498 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package queue - -import ( - "container/list" - "fmt" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/backend/heap" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/metrics" -) - -// activeQueuer is a wrapper for activeQ related operations. -// Its methods, except "unlocked" ones, take the lock inside. -// Note: be careful when using unlocked() methods. -// getLock() methods should be used only for unlocked() methods -// and it is forbidden to call any other activeQueuer's method under this lock. -type activeQueuer interface { - underLock(func(unlockedActiveQ unlockedActiveQueuer)) - underRLock(func(unlockedActiveQ unlockedActiveQueueReader)) - - update(newPod *v1.Pod, oldPodInfo *framework.QueuedPodInfo) *framework.QueuedPodInfo - delete(pInfo *framework.QueuedPodInfo) error - pop(logger klog.Logger) (*framework.QueuedPodInfo, error) - list() []*v1.Pod - len() int - has(pInfo *framework.QueuedPodInfo) bool - - listInFlightEvents() []interface{} - listInFlightPods() []*v1.Pod - clusterEventsForPod(logger klog.Logger, pInfo *framework.QueuedPodInfo) ([]*clusterEvent, error) - addEventsIfPodInFlight(oldPod, newPod *v1.Pod, events []framework.ClusterEvent) bool - addEventIfAnyInFlight(oldObj, newObj interface{}, event framework.ClusterEvent) bool - - schedulingCycle() int64 - done(pod types.UID) - close() - broadcast() -} - -// unlockedActiveQueuer defines activeQ methods that are not protected by the lock itself. -// underLock() method should be used to protect these methods. -type unlockedActiveQueuer interface { - unlockedActiveQueueReader - // add adds a new pod to the activeQ. - // The event should show which event triggered this addition and is used for the metric recording. - // This method should be called in activeQueue.underLock(). - add(pInfo *framework.QueuedPodInfo, event string) -} - -// unlockedActiveQueueReader defines activeQ read-only methods that are not protected by the lock itself. -// underLock() or underRLock() method should be used to protect these methods. -type unlockedActiveQueueReader interface { - // get returns the pod matching pInfo inside the activeQ. - // Returns false if the pInfo doesn't exist in the queue. - // This method should be called in activeQueue.underLock() or activeQueue.underRLock(). - get(pInfo *framework.QueuedPodInfo) (*framework.QueuedPodInfo, bool) - // has returns if pInfo exists in the queue. - // This method should be called in activeQueue.underLock() or activeQueue.underRLock(). - has(pInfo *framework.QueuedPodInfo) bool -} - -// unlockedActiveQueue defines activeQ methods that are not protected by the lock itself. -// activeQueue.underLock() or activeQueue.underRLock() method should be used to protect these methods. -type unlockedActiveQueue struct { - queue *heap.Heap[*framework.QueuedPodInfo] -} - -func newUnlockedActiveQueue(queue *heap.Heap[*framework.QueuedPodInfo]) *unlockedActiveQueue { - return &unlockedActiveQueue{ - queue: queue, - } -} - -// add adds a new pod to the activeQ. -// The event should show which event triggered this addition and is used for the metric recording. -// This method should be called in activeQueue.underLock(). -func (uaq *unlockedActiveQueue) add(pInfo *framework.QueuedPodInfo, event string) { - uaq.queue.AddOrUpdate(pInfo) - metrics.SchedulerQueueIncomingPods.WithLabelValues("active", event).Inc() -} - -// get returns the pod matching pInfo inside the activeQ. -// Returns false if the pInfo doesn't exist in the queue. -// This method should be called in activeQueue.underLock() or activeQueue.underRLock(). -func (uaq *unlockedActiveQueue) get(pInfo *framework.QueuedPodInfo) (*framework.QueuedPodInfo, bool) { - return uaq.queue.Get(pInfo) -} - -// has returns if pInfo exists in the queue. -// This method should be called in activeQueue.underLock() or activeQueue.underRLock(). -func (uaq *unlockedActiveQueue) has(pInfo *framework.QueuedPodInfo) bool { - return uaq.queue.Has(pInfo) -} - -// backoffQPopper defines method that is used to pop from the backoffQ when the activeQ is empty. -type backoffQPopper interface { - // popBackoff pops the pInfo from the podBackoffQ. - popBackoff() (*framework.QueuedPodInfo, error) - // len returns length of the podBackoffQ queue. - lenBackoff() int -} - -// activeQueue implements activeQueuer. All of the fields have to be protected using the lock. -type activeQueue struct { - // lock synchronizes all operations related to activeQ. - // It protects activeQ, inFlightPods, inFlightEvents, schedulingCycle and closed fields. - // Caution: DO NOT take "SchedulingQueue.lock" after taking "lock". - // You should always take "SchedulingQueue.lock" first, otherwise the queue could end up in deadlock. - // "lock" should not be taken after taking "backoffQueue.lock" or "nominator.nLock". - // Correct locking order is: SchedulingQueue.lock > lock > backoffQueue.lock > nominator.nLock. - lock sync.RWMutex - - // activeQ is heap structure that scheduler actively looks at to find pods to - // schedule. Head of heap is the highest priority pod. - queue *heap.Heap[*framework.QueuedPodInfo] - - // unlockedQueue is a wrapper of queue providing methods that are not locked themselves - // and can be used in the underLock() or underRLock(). - unlockedQueue *unlockedActiveQueue - - // cond is a condition that is notified when the pod is added to activeQ. - // When SchedulerPopFromBackoffQ feature is enabled, - // condition is also notified when the pod is added to backoffQ. - // It is used with lock. - cond sync.Cond - - // inFlightPods holds the UID of all pods which have been popped out for which Done - // hasn't been called yet - in other words, all pods that are currently being - // processed (being scheduled, in permit, or in the binding cycle). - // - // The values in the map are the entry of each pod in the inFlightEvents list. - // The value of that entry is the *v1.Pod at the time that scheduling of that - // pod started, which can be useful for logging or debugging. - inFlightPods map[types.UID]*list.Element - - // inFlightEvents holds the events received by the scheduling queue - // (entry value is clusterEvent) together with in-flight pods (entry - // value is *v1.Pod). Entries get added at the end while the mutex is - // locked, so they get serialized. - // - // The pod entries are added in Pop and used to track which events - // occurred after the pod scheduling attempt for that pod started. - // They get removed when the scheduling attempt is done, at which - // point all events that occurred in the meantime are processed. - // - // After removal of a pod, events at the start of the list are no - // longer needed because all of the other in-flight pods started - // later. Those events can be removed. - inFlightEvents *list.List - - // schedCycle represents sequence number of scheduling cycle and is incremented - // when a pod is popped. - schedCycle int64 - - // closed indicates that the queue is closed. - // It is mainly used to let Pop() exit its control loop while waiting for an item. - closed bool - - // isSchedulingQueueHintEnabled indicates whether the feature gate for the scheduling queue is enabled. - isSchedulingQueueHintEnabled bool - - metricsRecorder metrics.MetricAsyncRecorder - - // backoffQPopper is used to pop from backoffQ when activeQ is empty. - // It is non-nil only when SchedulerPopFromBackoffQ feature is enabled. - backoffQPopper backoffQPopper -} - -func newActiveQueue(queue *heap.Heap[*framework.QueuedPodInfo], isSchedulingQueueHintEnabled bool, metricRecorder metrics.MetricAsyncRecorder, backoffQPopper backoffQPopper) *activeQueue { - aq := &activeQueue{ - queue: queue, - inFlightPods: make(map[types.UID]*list.Element), - inFlightEvents: list.New(), - isSchedulingQueueHintEnabled: isSchedulingQueueHintEnabled, - metricsRecorder: metricRecorder, - unlockedQueue: newUnlockedActiveQueue(queue), - backoffQPopper: backoffQPopper, - } - aq.cond.L = &aq.lock - - return aq -} - -// underLock runs the fn function under the lock.Lock. -// fn can run unlockedActiveQueuer methods but should NOT run any other activeQueue method, -// as it would end up in deadlock. -func (aq *activeQueue) underLock(fn func(unlockedActiveQ unlockedActiveQueuer)) { - aq.lock.Lock() - defer aq.lock.Unlock() - fn(aq.unlockedQueue) -} - -// underLock runs the fn function under the lock.RLock. -// fn can run unlockedActiveQueueReader methods but should NOT run any other activeQueue method, -// as it would end up in deadlock. -func (aq *activeQueue) underRLock(fn func(unlockedActiveQ unlockedActiveQueueReader)) { - aq.lock.RLock() - defer aq.lock.RUnlock() - fn(aq.unlockedQueue) -} - -// update updates the pod in activeQ if oldPodInfo is already in the queue. -// It returns new pod info if updated, nil otherwise. -func (aq *activeQueue) update(newPod *v1.Pod, oldPodInfo *framework.QueuedPodInfo) *framework.QueuedPodInfo { - aq.lock.Lock() - defer aq.lock.Unlock() - - if pInfo, exists := aq.queue.Get(oldPodInfo); exists { - _ = pInfo.Update(newPod) - aq.queue.AddOrUpdate(pInfo) - return pInfo - } - return nil -} - -// delete deletes the pod info from activeQ. -func (aq *activeQueue) delete(pInfo *framework.QueuedPodInfo) error { - aq.lock.Lock() - defer aq.lock.Unlock() - - return aq.queue.Delete(pInfo) -} - -// pop removes the head of the queue and returns it. -// It blocks if the queue is empty and waits until a new item is added to the queue. -// It increments scheduling cycle when a pod is popped. -func (aq *activeQueue) pop(logger klog.Logger) (*framework.QueuedPodInfo, error) { - aq.lock.Lock() - defer aq.lock.Unlock() - - return aq.unlockedPop(logger) -} - -func (aq *activeQueue) unlockedPop(logger klog.Logger) (*framework.QueuedPodInfo, error) { - var pInfo *framework.QueuedPodInfo - for aq.queue.Len() == 0 { - // backoffQPopper is non-nil only if SchedulerPopFromBackoffQ feature is enabled. - // In case of non-empty backoffQ, try popping from there. - if aq.backoffQPopper != nil && aq.backoffQPopper.lenBackoff() != 0 { - break - } - // When the queue is empty, invocation of Pop() is blocked until new item is enqueued. - // When Close() is called, the p.closed is set and the condition is broadcast, - // which causes this loop to continue and return from the Pop(). - if aq.closed { - logger.V(2).Info("Scheduling queue is closed") - return nil, nil - } - aq.cond.Wait() - } - pInfo, err := aq.queue.Pop() - if err != nil { - if aq.backoffQPopper == nil { - return nil, err - } - // Try to pop from backoffQ when activeQ is empty. - pInfo, err = aq.backoffQPopper.popBackoff() - if err != nil { - return nil, err - } - metrics.SchedulerQueueIncomingPods.WithLabelValues("active", framework.PopFromBackoffQ).Inc() - } - pInfo.Attempts++ - pInfo.BackoffExpiration = time.Time{} - // In flight, no concurrent events yet. - if aq.isSchedulingQueueHintEnabled { - // If the pod is already in the map, we shouldn't overwrite the inFlightPods otherwise it'd lead to a memory leak. - // https://github.com/kubernetes/kubernetes/pull/127016 - if _, ok := aq.inFlightPods[pInfo.Pod.UID]; ok { - // Just report it as an error, but no need to stop the scheduler - // because it likely doesn't cause any visible issues from the scheduling perspective. - logger.Error(nil, "the same pod is tracked in multiple places in the scheduler, and just discard it", "pod", klog.KObj(pInfo.Pod)) - // Just ignore/discard this duplicated pod and try to pop the next one. - return aq.unlockedPop(logger) - } - - aq.metricsRecorder.ObserveInFlightEventsAsync(metrics.PodPoppedInFlightEvent, 1, false) - aq.inFlightPods[pInfo.Pod.UID] = aq.inFlightEvents.PushBack(pInfo.Pod) - } - aq.schedCycle++ - - // Update metrics and reset the set of unschedulable plugins for the next attempt. - for plugin := range pInfo.UnschedulablePlugins.Union(pInfo.PendingPlugins) { - metrics.UnschedulableReason(plugin, pInfo.Pod.Spec.SchedulerName).Dec() - } - pInfo.UnschedulablePlugins.Clear() - pInfo.PendingPlugins.Clear() - - return pInfo, nil -} - -// list returns all pods that are in the queue. -func (aq *activeQueue) list() []*v1.Pod { - aq.lock.RLock() - defer aq.lock.RUnlock() - var result []*v1.Pod - for _, pInfo := range aq.queue.List() { - result = append(result, pInfo.Pod) - } - return result -} - -// len returns length of the queue. -func (aq *activeQueue) len() int { - return aq.queue.Len() -} - -// has inform if pInfo exists in the queue. -func (aq *activeQueue) has(pInfo *framework.QueuedPodInfo) bool { - aq.lock.RLock() - defer aq.lock.RUnlock() - return aq.queue.Has(pInfo) -} - -// listInFlightEvents returns all inFlightEvents. -func (aq *activeQueue) listInFlightEvents() []interface{} { - aq.lock.RLock() - defer aq.lock.RUnlock() - var values []interface{} - for event := aq.inFlightEvents.Front(); event != nil; event = event.Next() { - values = append(values, event.Value) - } - return values -} - -// listInFlightPods returns all inFlightPods. -func (aq *activeQueue) listInFlightPods() []*v1.Pod { - aq.lock.RLock() - defer aq.lock.RUnlock() - var pods []*v1.Pod - for _, obj := range aq.inFlightPods { - pods = append(pods, obj.Value.(*v1.Pod)) - } - return pods -} - -// clusterEventsForPod gets all cluster events that have happened during pod for pInfo is being scheduled. -func (aq *activeQueue) clusterEventsForPod(logger klog.Logger, pInfo *framework.QueuedPodInfo) ([]*clusterEvent, error) { - aq.lock.RLock() - defer aq.lock.RUnlock() - logger.V(5).Info("Checking events for in-flight pod", "pod", klog.KObj(pInfo.Pod), "unschedulablePlugins", pInfo.UnschedulablePlugins, "inFlightEventsSize", aq.inFlightEvents.Len(), "inFlightPodsSize", len(aq.inFlightPods)) - - // AddUnschedulableIfNotPresent is called with the Pod at the end of scheduling or binding. - // So, given pInfo should have been Pop()ed before, - // we can assume pInfo must be recorded in inFlightPods and thus inFlightEvents. - inFlightPod, ok := aq.inFlightPods[pInfo.Pod.UID] - if !ok { - return nil, fmt.Errorf("in flight Pod isn't found in the scheduling queue. If you see this error log, it's likely a bug in the scheduler") - } - - var events []*clusterEvent - for event := inFlightPod.Next(); event != nil; event = event.Next() { - e, ok := event.Value.(*clusterEvent) - if !ok { - // Must be another in-flight Pod (*v1.Pod). Can be ignored. - continue - } - events = append(events, e) - } - return events, nil -} - -// addEventsIfPodInFlight adds clusterEvent to inFlightEvents if the newPod is in inFlightPods. -// It returns true if pushed the event to the inFlightEvents. -func (aq *activeQueue) addEventsIfPodInFlight(oldPod, newPod *v1.Pod, events []framework.ClusterEvent) bool { - aq.lock.Lock() - defer aq.lock.Unlock() - - _, ok := aq.inFlightPods[newPod.UID] - if ok { - for _, event := range events { - aq.metricsRecorder.ObserveInFlightEventsAsync(event.Label(), 1, false) - aq.inFlightEvents.PushBack(&clusterEvent{ - event: event, - oldObj: oldPod, - newObj: newPod, - }) - } - } - return ok -} - -// addEventIfAnyInFlight adds clusterEvent to inFlightEvents if any pod is in inFlightPods. -// It returns true if pushed the event to the inFlightEvents. -func (aq *activeQueue) addEventIfAnyInFlight(oldObj, newObj interface{}, event framework.ClusterEvent) bool { - aq.lock.Lock() - defer aq.lock.Unlock() - - if len(aq.inFlightPods) != 0 { - aq.metricsRecorder.ObserveInFlightEventsAsync(event.Label(), 1, false) - aq.inFlightEvents.PushBack(&clusterEvent{ - event: event, - oldObj: oldObj, - newObj: newObj, - }) - return true - } - return false -} - -func (aq *activeQueue) schedulingCycle() int64 { - aq.lock.RLock() - defer aq.lock.RUnlock() - return aq.schedCycle -} - -// done must be called for pod returned by Pop. This allows the queue to -// keep track of which pods are currently being processed. -func (aq *activeQueue) done(pod types.UID) { - aq.lock.Lock() - defer aq.lock.Unlock() - - aq.unlockedDone(pod) -} - -// unlockedDone is used by the activeQueue internally and doesn't take the lock itself. -// It assumes the lock is already taken outside before the method is called. -func (aq *activeQueue) unlockedDone(pod types.UID) { - inFlightPod, ok := aq.inFlightPods[pod] - if !ok { - // This Pod is already done()ed. - return - } - delete(aq.inFlightPods, pod) - - // Remove the pod from the list. - aq.inFlightEvents.Remove(inFlightPod) - - aggrMetricsCounter := map[string]int{} - // Remove events which are only referred to by this Pod - // so that the inFlightEvents list doesn't grow infinitely. - // If the pod was at the head of the list, then all - // events between it and the next pod are no longer needed - // and can be removed. - for { - e := aq.inFlightEvents.Front() - if e == nil { - // Empty list. - break - } - ev, ok := e.Value.(*clusterEvent) - if !ok { - // A pod, must stop pruning. - break - } - aq.inFlightEvents.Remove(e) - aggrMetricsCounter[ev.event.Label()]-- - } - - for evLabel, count := range aggrMetricsCounter { - aq.metricsRecorder.ObserveInFlightEventsAsync(evLabel, float64(count), false) - } - - aq.metricsRecorder.ObserveInFlightEventsAsync(metrics.PodPoppedInFlightEvent, -1, - // If it's the last Pod in inFlightPods, we should force-flush the metrics. - // Otherwise, especially in small clusters, which don't get a new Pod frequently, - // the metrics might not be flushed for a long time. - len(aq.inFlightPods) == 0) -} - -// close closes the activeQueue. -func (aq *activeQueue) close() { - aq.lock.Lock() - defer aq.lock.Unlock() - // We should call done() for all in-flight pods to clean up the inFlightEvents metrics. - // It's safe even if the binding cycle running asynchronously calls done() afterwards - // done() will just be a no-op. - for pod := range aq.inFlightPods { - aq.unlockedDone(pod) - } - aq.closed = true -} - -// broadcast notifies the pop() operation that new pod(s) was added to the activeQueue. -func (aq *activeQueue) broadcast() { - aq.cond.Broadcast() -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/backoff_queue.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/backoff_queue.go deleted file mode 100644 index 6e0bbd680..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/backoff_queue.go +++ /dev/null @@ -1,405 +0,0 @@ -/* -Copyright 2025 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package queue - -import ( - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/backend/heap" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/utils/clock" -) - -// backoffQOrderingWindowDuration is a duration of an ordering window in the podBackoffQ. -// In each window, represented as a whole second, pods are ordered by priority. -// It is the same as interval of flushing the pods from the podBackoffQ to the activeQ, to flush the whole windows there. -// This works only if PopFromBackoffQ feature is enabled. -// See the KEP-5142 (http://kep.k8s.io/5142) for rationale. -const backoffQOrderingWindowDuration = time.Second - -// backoffQueuer is a wrapper for backoffQ related operations. -// Its methods that relies on the queues, take the lock inside. -type backoffQueuer interface { - // isPodBackingoff returns true if a pod is still waiting for its backoff timer. - // If this returns true, the pod should not be re-tried. - // If the pod backoff time is in the actual ordering window, it should still be backing off. - isPodBackingoff(podInfo *framework.QueuedPodInfo) bool - // popAllBackoffCompleted pops all pods from podBackoffQ and podErrorBackoffQ that completed backoff. - popAllBackoffCompleted(logger klog.Logger) []*framework.QueuedPodInfo - - // podInitialBackoffDuration returns initial backoff duration that pod can get. - podInitialBackoffDuration() time.Duration - // podMaxBackoffDuration returns maximum backoff duration that pod can get. - podMaxBackoffDuration() time.Duration - // waitUntilAlignedWithOrderingWindow waits until the time reaches a multiple of backoffQOrderingWindowDuration. - // It then runs the f function at the backoffQOrderingWindowDuration interval using a ticker. - // It's important to align the flushing time, because podBackoffQ's ordering is based on the windows - // and whole windows have to be flushed at one time without a visible latency. - waitUntilAlignedWithOrderingWindow(f func(), stopCh <-chan struct{}) - - // add adds the pInfo to backoffQueue. - // The event should show which event triggered this addition and is used for the metric recording. - // It also ensures that pInfo is not in both queues. - add(logger klog.Logger, pInfo *framework.QueuedPodInfo, event string) - // update updates the pod in backoffQueue if oldPodInfo is already in the queue. - // It returns new pod info if updated, nil otherwise. - update(newPod *v1.Pod, oldPodInfo *framework.QueuedPodInfo) *framework.QueuedPodInfo - // delete deletes the pInfo from backoffQueue. - // It returns true if the pod was deleted. - delete(pInfo *framework.QueuedPodInfo) bool - // get returns the pInfo matching given pInfoLookup, if exists. - get(pInfoLookup *framework.QueuedPodInfo) (*framework.QueuedPodInfo, bool) - // has inform if pInfo exists in the queue. - has(pInfo *framework.QueuedPodInfo) bool - // list returns all pods that are in the queue. - list() []*v1.Pod - // len returns length of the queue. - len() int -} - -// backoffQueue implements backoffQueuer and wraps two queues inside, -// providing seamless access as if it were one queue. -type backoffQueue struct { - // lock synchronizes all operations related to backoffQ. - // It protects both podBackoffQ and podErrorBackoffQ. - // Caution: DO NOT take "SchedulingQueue.lock" or "activeQueue.lock" after taking "lock". - // You should always take "SchedulingQueue.lock" and "activeQueue.lock" first, otherwise the queue could end up in deadlock. - // "lock" should not be taken after taking "nominator.nLock". - // Correct locking order is: SchedulingQueue.lock > activeQueue.lock > lock > nominator.nLock. - lock sync.RWMutex - - clock clock.WithTicker - - // podBackoffQ is a heap ordered by backoff expiry. Pods which have completed backoff - // are popped from this heap before the scheduler looks at activeQ - podBackoffQ *heap.Heap[*framework.QueuedPodInfo] - // podErrorBackoffQ is a heap ordered by error backoff expiry. Pods which have completed backoff - // are popped from this heap before the scheduler looks at activeQ - podErrorBackoffQ *heap.Heap[*framework.QueuedPodInfo] - - podInitialBackoff time.Duration - podMaxBackoff time.Duration - // activeQLessFn is used as an eventual less function if two backoff times are equal, - // when the SchedulerPopFromBackoffQ feature is enabled. - activeQLessFn framework.LessFunc - - // isPopFromBackoffQEnabled indicates whether the feature gate SchedulerPopFromBackoffQ is enabled. - isPopFromBackoffQEnabled bool -} - -func newBackoffQueue(clock clock.WithTicker, podInitialBackoffDuration time.Duration, podMaxBackoffDuration time.Duration, activeQLessFn framework.LessFunc, popFromBackoffQEnabled bool) *backoffQueue { - bq := &backoffQueue{ - clock: clock, - podInitialBackoff: podInitialBackoffDuration, - podMaxBackoff: podMaxBackoffDuration, - isPopFromBackoffQEnabled: popFromBackoffQEnabled, - activeQLessFn: activeQLessFn, - } - podBackoffQLessFn := bq.lessBackoffCompleted - if popFromBackoffQEnabled { - podBackoffQLessFn = bq.lessBackoffCompletedWithPriority - } - bq.podBackoffQ = heap.NewWithRecorder(podInfoKeyFunc, podBackoffQLessFn, metrics.NewBackoffPodsRecorder()) - bq.podErrorBackoffQ = heap.NewWithRecorder(podInfoKeyFunc, bq.lessBackoffCompleted, metrics.NewBackoffPodsRecorder()) - - return bq -} - -// podInitialBackoffDuration returns initial backoff duration that pod can get. -func (bq *backoffQueue) podInitialBackoffDuration() time.Duration { - return bq.podInitialBackoff -} - -// podMaxBackoffDuration returns maximum backoff duration that pod can get. -func (bq *backoffQueue) podMaxBackoffDuration() time.Duration { - return bq.podMaxBackoff -} - -// alignToWindow truncates the provided time to the podBackoffQ ordering window. -// It returns the lowest possible timestamp in the window. -func (bq *backoffQueue) alignToWindow(t time.Time) time.Time { - if !bq.isPopFromBackoffQEnabled { - return t - } - return t.Truncate(backoffQOrderingWindowDuration) -} - -// waitUntilAlignedWithOrderingWindow waits until the time reaches a multiple of backoffQOrderingWindowDuration. -// It then runs the f function at the backoffQOrderingWindowDuration interval using a ticker. -// It's important to align the flushing time, because podBackoffQ's ordering is based on the windows -// and whole windows have to be flushed at one time without a visible latency. -func (bq *backoffQueue) waitUntilAlignedWithOrderingWindow(f func(), stopCh <-chan struct{}) { - now := bq.clock.Now() - // Wait until the time reaches the multiple of backoffQOrderingWindowDuration. - durationToNextWindow := bq.alignToWindow(now.Add(backoffQOrderingWindowDuration)).Sub(now) - timer := bq.clock.NewTimer(durationToNextWindow) - select { - case <-stopCh: - timer.Stop() - return - case <-timer.C(): - } - - // Run a ticker to make sure the invocations of f function - // are aligned with the backoffQ's ordering window. - ticker := bq.clock.NewTicker(backoffQOrderingWindowDuration) - for { - select { - case <-stopCh: - return - default: - } - - f() - - // NOTE: b/c there is no priority selection in golang - // it is possible for this to race, meaning we could - // trigger ticker.C and stopCh, and ticker.C select falls through. - // In order to mitigate we re-check stopCh at the beginning - // of every loop to prevent extra executions of f(). - select { - case <-stopCh: - ticker.Stop() - return - case <-ticker.C(): - } - } -} - -// lessBackoffCompletedWithPriority is a less function of podBackoffQ if PopFromBackoffQ feature is enabled. -// It orders the pods in the same BackoffOrderingWindow the same as the activeQ will do to improve popping order from backoffQ when activeQ is empty. -func (bq *backoffQueue) lessBackoffCompletedWithPriority(pInfo1, pInfo2 *framework.QueuedPodInfo) bool { - bo1 := bq.getBackoffTime(pInfo1) - bo2 := bq.getBackoffTime(pInfo2) - if !bo1.Equal(bo2) { - return bo1.Before(bo2) - } - // If the backoff time is the same, sort the pod in the same manner as activeQ does. - return bq.activeQLessFn(pInfo1, pInfo2) -} - -// lessBackoffCompleted is a less function of podErrorBackoffQ. -func (bq *backoffQueue) lessBackoffCompleted(pInfo1, pInfo2 *framework.QueuedPodInfo) bool { - bo1 := bq.getBackoffTime(pInfo1) - bo2 := bq.getBackoffTime(pInfo2) - return bo1.Before(bo2) -} - -// isPodBackingoff returns true if a pod is still waiting for its backoff timer. -// If this returns true, the pod should not be re-tried. -// If the pod backoff time is in the actual ordering window, it should still be backing off. -func (bq *backoffQueue) isPodBackingoff(podInfo *framework.QueuedPodInfo) bool { - boTime := bq.getBackoffTime(podInfo) - // Don't use After, because in case of windows equality we want to return true. - return !boTime.Before(bq.alignToWindow(bq.clock.Now())) -} - -// getBackoffTime returns the time that podInfo completes backoff. -// It caches the result in podInfo.BackoffExpiration and returns this value in subsequent calls. -// The cache will be cleared when this pod is poped from the scheduling queue again (i.e., at activeQ's pop), -// because of the fact that the backoff time is calculated based on podInfo.Attempts, -// which doesn't get changed until the pod's scheduling is retried. -func (bq *backoffQueue) getBackoffTime(podInfo *framework.QueuedPodInfo) time.Time { - if podInfo.Attempts == 0 { - // Don't store backoff expiration if the duration is 0 - // to correctly handle isPodBackingoff, if pod should skip backoff, when it wasn't tried at all. - return time.Time{} - } - if podInfo.BackoffExpiration.IsZero() { - duration := bq.calculateBackoffDuration(podInfo) - podInfo.BackoffExpiration = bq.alignToWindow(podInfo.Timestamp.Add(duration)) - } - return podInfo.BackoffExpiration -} - -// calculateBackoffDuration is a helper function for calculating the backoffDuration -// based on the number of attempts the pod has made. -func (bq *backoffQueue) calculateBackoffDuration(podInfo *framework.QueuedPodInfo) time.Duration { - if podInfo.Attempts == 0 { - // When the Pod hasn't experienced any scheduling attempts, - // they aren't obliged to get a backoff penalty at all. - return 0 - } - - duration := bq.podInitialBackoff - for i := 1; i < podInfo.Attempts; i++ { - // Use subtraction instead of addition or multiplication to avoid overflow. - if duration > bq.podMaxBackoff-duration { - return bq.podMaxBackoff - } - duration += duration - } - return duration -} - -func (bq *backoffQueue) popAllBackoffCompletedWithQueue(logger klog.Logger, queue *heap.Heap[*framework.QueuedPodInfo]) []*framework.QueuedPodInfo { - var poppedPods []*framework.QueuedPodInfo - for { - pInfo, ok := queue.Peek() - if !ok || pInfo == nil { - break - } - pod := pInfo.Pod - if bq.isPodBackingoff(pInfo) { - break - } - _, err := queue.Pop() - if err != nil { - logger.Error(err, "Unable to pop pod from backoff queue despite backoff completion", "pod", klog.KObj(pod)) - break - } - poppedPods = append(poppedPods, pInfo) - } - return poppedPods -} - -// popAllBackoffCompleted pops all pods from podBackoffQ and podErrorBackoffQ that completed backoff. -func (bq *backoffQueue) popAllBackoffCompleted(logger klog.Logger) []*framework.QueuedPodInfo { - bq.lock.Lock() - defer bq.lock.Unlock() - - // Ensure both queues are called - return append(bq.popAllBackoffCompletedWithQueue(logger, bq.podBackoffQ), bq.popAllBackoffCompletedWithQueue(logger, bq.podErrorBackoffQ)...) -} - -// add adds the pInfo to backoffQueue. -// The event should show which event triggered this addition and is used for the metric recording. -// It also ensures that pInfo is not in both queues. -func (bq *backoffQueue) add(logger klog.Logger, pInfo *framework.QueuedPodInfo, event string) { - bq.lock.Lock() - defer bq.lock.Unlock() - - // If pod has empty both unschedulable plugins and pending plugins, - // it means that it failed because of error and should be moved to podErrorBackoffQ. - if pInfo.UnschedulablePlugins.Len() == 0 && pInfo.PendingPlugins.Len() == 0 { - bq.podErrorBackoffQ.AddOrUpdate(pInfo) - // Ensure the pod is not in the podBackoffQ and report the error if it happens. - err := bq.podBackoffQ.Delete(pInfo) - if err == nil { - logger.Error(nil, "BackoffQueue add() was called with a pod that was already in the podBackoffQ", "pod", klog.KObj(pInfo.Pod)) - return - } - metrics.SchedulerQueueIncomingPods.WithLabelValues("backoff", event).Inc() - return - } - bq.podBackoffQ.AddOrUpdate(pInfo) - // Ensure the pod is not in the podErrorBackoffQ and report the error if it happens. - err := bq.podErrorBackoffQ.Delete(pInfo) - if err == nil { - logger.Error(nil, "BackoffQueue add() was called with a pod that was already in the podErrorBackoffQ", "pod", klog.KObj(pInfo.Pod)) - return - } - metrics.SchedulerQueueIncomingPods.WithLabelValues("backoff", event).Inc() -} - -// update updates the pod in backoffQueue if oldPodInfo is already in the queue. -// It returns new pod info if updated, nil otherwise. -func (bq *backoffQueue) update(newPod *v1.Pod, oldPodInfo *framework.QueuedPodInfo) *framework.QueuedPodInfo { - bq.lock.Lock() - defer bq.lock.Unlock() - - // If the pod is in the backoff queue, update it there. - if pInfo, exists := bq.podBackoffQ.Get(oldPodInfo); exists { - _ = pInfo.Update(newPod) - bq.podBackoffQ.AddOrUpdate(pInfo) - return pInfo - } - // If the pod is in the error backoff queue, update it there. - if pInfo, exists := bq.podErrorBackoffQ.Get(oldPodInfo); exists { - _ = pInfo.Update(newPod) - bq.podErrorBackoffQ.AddOrUpdate(pInfo) - return pInfo - } - return nil -} - -// delete deletes the pInfo from backoffQueue. -// It returns true if the pod was deleted. -func (bq *backoffQueue) delete(pInfo *framework.QueuedPodInfo) bool { - bq.lock.Lock() - defer bq.lock.Unlock() - - if bq.podBackoffQ.Delete(pInfo) == nil { - return true - } - return bq.podErrorBackoffQ.Delete(pInfo) == nil -} - -// popBackoff pops the pInfo from the podBackoffQ. -// It returns error if the queue is empty. -// This doesn't pop the pods from the podErrorBackoffQ. -func (bq *backoffQueue) popBackoff() (*framework.QueuedPodInfo, error) { - bq.lock.Lock() - defer bq.lock.Unlock() - - return bq.podBackoffQ.Pop() -} - -// get returns the pInfo matching given pInfoLookup, if exists. -func (bq *backoffQueue) get(pInfoLookup *framework.QueuedPodInfo) (*framework.QueuedPodInfo, bool) { - bq.lock.RLock() - defer bq.lock.RUnlock() - - pInfo, exists := bq.podBackoffQ.Get(pInfoLookup) - if exists { - return pInfo, true - } - return bq.podErrorBackoffQ.Get(pInfoLookup) -} - -// has inform if pInfo exists in the queue. -func (bq *backoffQueue) has(pInfo *framework.QueuedPodInfo) bool { - bq.lock.RLock() - defer bq.lock.RUnlock() - - return bq.podBackoffQ.Has(pInfo) || bq.podErrorBackoffQ.Has(pInfo) -} - -// list returns all pods that are in the queue. -func (bq *backoffQueue) list() []*v1.Pod { - bq.lock.RLock() - defer bq.lock.RUnlock() - - var result []*v1.Pod - for _, pInfo := range bq.podBackoffQ.List() { - result = append(result, pInfo.Pod) - } - for _, pInfo := range bq.podErrorBackoffQ.List() { - result = append(result, pInfo.Pod) - } - return result -} - -// len returns length of the queue. -func (bq *backoffQueue) len() int { - bq.lock.RLock() - defer bq.lock.RUnlock() - - return bq.podBackoffQ.Len() + bq.podErrorBackoffQ.Len() -} - -// lenBackoff returns length of the podBackoffQ. -func (bq *backoffQueue) lenBackoff() int { - bq.lock.RLock() - defer bq.lock.RUnlock() - - return bq.podBackoffQ.Len() -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/nominator.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/nominator.go deleted file mode 100644 index 4d6ceaabc..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/nominator.go +++ /dev/null @@ -1,195 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package queue - -import ( - "slices" - "sync" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - listersv1 "k8s.io/client-go/listers/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// nominator is a structure that stores pods nominated to run on nodes. -// It exists because nominatedNodeName of pod objects stored in the structure -// may be different than what scheduler has here. We should be able to find pods -// by their UID and update/delete them. -type nominator struct { - // nLock synchronizes all operations related to nominator. - // It should not be used anywhere else. - // Caution: DO NOT take ("SchedulingQueue.lock" or "activeQueue.lock" or "backoffQueue.lock") after taking "nLock". - // You should always take "SchedulingQueue.lock" and "activeQueue.lock" and "backoffQueue.lock" first, - // otherwise the nominator could end up in deadlock. - // Correct locking order is: SchedulingQueue.lock > activeQueue.lock = backoffQueue.lock > nLock. - nLock sync.RWMutex - - // podLister is used to verify if the given pod is alive. - podLister listersv1.PodLister - // nominatedPods is a map keyed by a node name and the value is a list of - // pods which are nominated to run on the node. These are pods which can be in - // the activeQ or unschedulablePods. - nominatedPods map[string][]podRef - // nominatedPodToNode is map keyed by a Pod UID to the node name where it is - // nominated. - nominatedPodToNode map[types.UID]string -} - -func newPodNominator(podLister listersv1.PodLister) *nominator { - return &nominator{ - podLister: podLister, - nominatedPods: make(map[string][]podRef), - nominatedPodToNode: make(map[types.UID]string), - } -} - -// AddNominatedPod adds a pod to the nominated pods of the given node. -// This is called during the preemption process after a node is nominated to run -// the pod. We update the structure before sending a request to update the pod -// object to avoid races with the following scheduling cycles. -func (npm *nominator) AddNominatedPod(logger klog.Logger, pi *framework.PodInfo, nominatingInfo *framework.NominatingInfo) { - npm.nLock.Lock() - npm.addNominatedPodUnlocked(logger, pi, nominatingInfo) - npm.nLock.Unlock() -} - -func (npm *nominator) addNominatedPodUnlocked(logger klog.Logger, pi *framework.PodInfo, nominatingInfo *framework.NominatingInfo) { - // Always delete the pod if it already exists, to ensure we never store more than - // one instance of the pod. - npm.deleteUnlocked(pi.Pod) - - var nodeName string - if nominatingInfo.Mode() == framework.ModeOverride { - nodeName = nominatingInfo.NominatedNodeName - } else if nominatingInfo.Mode() == framework.ModeNoop { - if pi.Pod.Status.NominatedNodeName == "" { - return - } - nodeName = pi.Pod.Status.NominatedNodeName - } - - if npm.podLister != nil { - // If the pod was removed or if it was already scheduled, don't nominate it. - updatedPod, err := npm.podLister.Pods(pi.Pod.Namespace).Get(pi.Pod.Name) - if err != nil { - logger.V(4).Info("Pod doesn't exist in podLister, aborted adding it to the nominator", "pod", klog.KObj(pi.Pod)) - return - } - if updatedPod.Spec.NodeName != "" { - logger.V(4).Info("Pod is already scheduled to a node, aborted adding it to the nominator", "pod", klog.KObj(pi.Pod), "node", updatedPod.Spec.NodeName) - return - } - } - - npm.nominatedPodToNode[pi.Pod.UID] = nodeName - for _, np := range npm.nominatedPods[nodeName] { - if np.uid == pi.Pod.UID { - logger.V(4).Info("Pod already exists in the nominator", "pod", np.uid) - return - } - } - npm.nominatedPods[nodeName] = append(npm.nominatedPods[nodeName], podToRef(pi.Pod)) -} - -// UpdateNominatedPod updates the with . -func (npm *nominator) UpdateNominatedPod(logger klog.Logger, oldPod *v1.Pod, newPodInfo *framework.PodInfo) { - npm.nLock.Lock() - defer npm.nLock.Unlock() - // In some cases, an Update event with no "NominatedNode" present is received right - // after a node("NominatedNode") is reserved for this pod in memory. - // In this case, we need to keep reserving the NominatedNode when updating the pod pointer. - var nominatingInfo *framework.NominatingInfo - // We won't fall into below `if` block if the Update event represents: - // (1) NominatedNode info is added - // (2) NominatedNode info is updated - // (3) NominatedNode info is removed - if nominatedNodeName(oldPod) == "" && nominatedNodeName(newPodInfo.Pod) == "" { - if nnn, ok := npm.nominatedPodToNode[oldPod.UID]; ok { - // This is the only case we should continue reserving the NominatedNode - nominatingInfo = &framework.NominatingInfo{ - NominatingMode: framework.ModeOverride, - NominatedNodeName: nnn, - } - } - } - // We update irrespective of the nominatedNodeName changed or not, to ensure - // that pod pointer is updated. - npm.deleteUnlocked(oldPod) - npm.addNominatedPodUnlocked(logger, newPodInfo, nominatingInfo) -} - -// DeleteNominatedPodIfExists deletes from nominatedPods. -func (npm *nominator) DeleteNominatedPodIfExists(pod *v1.Pod) { - npm.nLock.Lock() - npm.deleteUnlocked(pod) - npm.nLock.Unlock() -} - -func (npm *nominator) deleteUnlocked(p *v1.Pod) { - nnn, ok := npm.nominatedPodToNode[p.UID] - if !ok { - return - } - for i, np := range npm.nominatedPods[nnn] { - if np.uid == p.UID { - npm.nominatedPods[nnn] = append(npm.nominatedPods[nnn][:i], npm.nominatedPods[nnn][i+1:]...) - if len(npm.nominatedPods[nnn]) == 0 { - delete(npm.nominatedPods, nnn) - } - break - } - } - delete(npm.nominatedPodToNode, p.UID) -} - -func (npm *nominator) nominatedPodsForNode(nodeName string) []podRef { - npm.nLock.RLock() - defer npm.nLock.RUnlock() - return slices.Clone(npm.nominatedPods[nodeName]) -} - -// nominatedNodeName returns nominated node name of a Pod. -func nominatedNodeName(pod *v1.Pod) string { - return pod.Status.NominatedNodeName -} - -type podRef struct { - name string - namespace string - uid types.UID -} - -func podToRef(pod *v1.Pod) podRef { - return podRef{ - name: pod.Name, - namespace: pod.Namespace, - uid: pod.UID, - } -} - -func (np podRef) toPod() *v1.Pod { - return &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: np.name, - Namespace: np.namespace, - UID: np.uid, - }, - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go deleted file mode 100644 index 69eae17fd..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/scheduling_queue.go +++ /dev/null @@ -1,1401 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This file contains structures that implement scheduling queue types. -// Scheduling queues hold pods waiting to be scheduled. This file implements a -// priority queue which has two sub queues and a additional data structure, -// namely: activeQ, backoffQ and unschedulablePods. -// - activeQ holds pods that are being considered for scheduling. -// - backoffQ holds pods that moved from unschedulablePods and will move to -// activeQ when their backoff periods complete. -// - unschedulablePods holds pods that were already attempted for scheduling and -// are currently determined to be unschedulable. - -package queue - -import ( - "context" - "fmt" - "math/rand" - "reflect" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/client-go/informers" - listersv1 "k8s.io/client-go/listers/core/v1" - "k8s.io/client-go/tools/cache" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/scheduler/backend/heap" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/scheduler/util" - "k8s.io/utils/clock" -) - -const ( - // DefaultPodMaxInUnschedulablePodsDuration is the default value for the maximum - // time a pod can stay in unschedulablePods. If a pod stays in unschedulablePods - // for longer than this value, the pod will be moved from unschedulablePods to - // backoffQ or activeQ. If this value is empty, the default value (5min) - // will be used. - DefaultPodMaxInUnschedulablePodsDuration time.Duration = 5 * time.Minute - // Scheduling queue names - activeQ = "Active" - backoffQ = "Backoff" - unschedulablePods = "Unschedulable" - - preEnqueue = "PreEnqueue" -) - -const ( - // DefaultPodInitialBackoffDuration is the default value for the initial backoff duration - // for unschedulable pods. To change the default podInitialBackoffDurationSeconds used by the - // scheduler, update the ComponentConfig value in defaults.go - DefaultPodInitialBackoffDuration time.Duration = 1 * time.Second - // DefaultPodMaxBackoffDuration is the default value for the max backoff duration - // for unschedulable pods. To change the default podMaxBackoffDurationSeconds used by the - // scheduler, update the ComponentConfig value in defaults.go - DefaultPodMaxBackoffDuration time.Duration = 10 * time.Second -) - -// PreEnqueueCheck is a function type. It's used to build functions that -// run against a Pod and the caller can choose to enqueue or skip the Pod -// by the checking result. -type PreEnqueueCheck func(pod *v1.Pod) bool - -// SchedulingQueue is an interface for a queue to store pods waiting to be scheduled. -// The interface follows a pattern similar to cache.FIFO and cache.Heap and -// makes it easy to use those data structures as a SchedulingQueue. -type SchedulingQueue interface { - framework.PodNominator - Add(logger klog.Logger, pod *v1.Pod) - // Activate moves the given pods to activeQ. - // If a pod isn't found in unschedulablePods or backoffQ and it's in-flight, - // the wildcard event is registered so that the pod will be requeued when it comes back. - // But, if a pod isn't found in unschedulablePods or backoffQ and it's not in-flight (i.e., completely unknown pod), - // Activate would ignore the pod. - Activate(logger klog.Logger, pods map[string]*v1.Pod) - // AddUnschedulableIfNotPresent adds an unschedulable pod back to scheduling queue. - // The podSchedulingCycle represents the current scheduling cycle number which can be - // returned by calling SchedulingCycle(). - AddUnschedulableIfNotPresent(logger klog.Logger, pod *framework.QueuedPodInfo, podSchedulingCycle int64) error - // SchedulingCycle returns the current number of scheduling cycle which is - // cached by scheduling queue. Normally, incrementing this number whenever - // a pod is popped (e.g. called Pop()) is enough. - SchedulingCycle() int64 - // Pop removes the head of the queue and returns it. It blocks if the - // queue is empty and waits until a new item is added to the queue. - Pop(logger klog.Logger) (*framework.QueuedPodInfo, error) - // Done must be called for pod returned by Pop. This allows the queue to - // keep track of which pods are currently being processed. - Done(types.UID) - Update(logger klog.Logger, oldPod, newPod *v1.Pod) - Delete(pod *v1.Pod) - // Important Note: preCheck shouldn't include anything that depends on the in-tree plugins' logic. - // (e.g., filter Pods based on added/updated Node's capacity, etc.) - // We know currently some do, but we'll eventually remove them in favor of the scheduling queue hint. - MoveAllToActiveOrBackoffQueue(logger klog.Logger, event framework.ClusterEvent, oldObj, newObj interface{}, preCheck PreEnqueueCheck) - AssignedPodAdded(logger klog.Logger, pod *v1.Pod) - AssignedPodUpdated(logger klog.Logger, oldPod, newPod *v1.Pod, event framework.ClusterEvent) - - // Close closes the SchedulingQueue so that the goroutine which is - // waiting to pop items can exit gracefully. - Close() - // Run starts the goroutines managing the queue. - Run(logger klog.Logger) - - // The following functions are supposed to be used only for testing or debugging. - GetPod(name, namespace string) (*framework.QueuedPodInfo, bool) - PendingPods() ([]*v1.Pod, string) - InFlightPods() []*v1.Pod - PodsInActiveQ() []*v1.Pod - // PodsInBackoffQ returns all the Pods in the backoffQ. - PodsInBackoffQ() []*v1.Pod - UnschedulablePods() []*v1.Pod -} - -// NewSchedulingQueue initializes a priority queue as a new scheduling queue. -func NewSchedulingQueue( - lessFn framework.LessFunc, - informerFactory informers.SharedInformerFactory, - opts ...Option) SchedulingQueue { - return NewPriorityQueue(lessFn, informerFactory, opts...) -} - -// PriorityQueue implements a scheduling queue. -// The head of PriorityQueue is the highest priority pending pod. This structure -// has two sub queues and a additional data structure, namely: activeQ, -// backoffQ and unschedulablePods. -// - activeQ holds pods that are being considered for scheduling. -// - backoffQ holds pods that moved from unschedulablePods and will move to -// activeQ when their backoff periods complete. -// - unschedulablePods holds pods that were already attempted for scheduling and -// are currently determined to be unschedulable. -type PriorityQueue struct { - *nominator - - stop chan struct{} - clock clock.WithTicker - - // lock takes precedence and should be taken first, - // before any other locks in the queue (activeQueue.lock or backoffQueue.lock or nominator.nLock). - // Correct locking order is: lock > activeQueue.lock > backoffQueue.lock > nominator.nLock. - lock sync.RWMutex - - // the maximum time a pod can stay in the unschedulablePods. - podMaxInUnschedulablePodsDuration time.Duration - - activeQ activeQueuer - backoffQ backoffQueuer - // unschedulablePods holds pods that have been tried and determined unschedulable. - unschedulablePods *UnschedulablePods - // moveRequestCycle caches the sequence number of scheduling cycle when we - // received a move request. Unschedulable pods in and before this scheduling - // cycle will be put back to activeQueue if we were trying to schedule them - // when we received move request. - // TODO: this will be removed after SchedulingQueueHint goes to stable and the feature gate is removed. - moveRequestCycle int64 - - // preEnqueuePluginMap is keyed with profile name, valued with registered preEnqueue plugins. - preEnqueuePluginMap map[string][]framework.PreEnqueuePlugin - // queueingHintMap is keyed with profile name, valued with registered queueing hint functions. - queueingHintMap QueueingHintMapPerProfile - - nsLister listersv1.NamespaceLister - - metricsRecorder metrics.MetricAsyncRecorder - // pluginMetricsSamplePercent is the percentage of plugin metrics to be sampled. - pluginMetricsSamplePercent int - - // isSchedulingQueueHintEnabled indicates whether the feature gate for the scheduling queue is enabled. - isSchedulingQueueHintEnabled bool - // isPopFromBackoffQEnabled indicates whether the feature gate SchedulerPopFromBackoffQ is enabled. - isPopFromBackoffQEnabled bool -} - -// QueueingHintFunction is the wrapper of QueueingHintFn that has PluginName. -type QueueingHintFunction struct { - PluginName string - QueueingHintFn framework.QueueingHintFn -} - -// clusterEvent has the event and involved objects. -type clusterEvent struct { - event framework.ClusterEvent - // oldObj is the object that involved this event. - oldObj interface{} - // newObj is the object that involved this event. - newObj interface{} -} - -type priorityQueueOptions struct { - clock clock.WithTicker - podInitialBackoffDuration time.Duration - podMaxBackoffDuration time.Duration - podMaxInUnschedulablePodsDuration time.Duration - podLister listersv1.PodLister - metricsRecorder metrics.MetricAsyncRecorder - pluginMetricsSamplePercent int - preEnqueuePluginMap map[string][]framework.PreEnqueuePlugin - queueingHintMap QueueingHintMapPerProfile -} - -// Option configures a PriorityQueue -type Option func(*priorityQueueOptions) - -// WithClock sets clock for PriorityQueue, the default clock is clock.RealClock. -func WithClock(clock clock.WithTicker) Option { - return func(o *priorityQueueOptions) { - o.clock = clock - } -} - -// WithPodInitialBackoffDuration sets pod initial backoff duration for PriorityQueue. -func WithPodInitialBackoffDuration(duration time.Duration) Option { - return func(o *priorityQueueOptions) { - o.podInitialBackoffDuration = duration - } -} - -// WithPodMaxBackoffDuration sets pod max backoff duration for PriorityQueue. -func WithPodMaxBackoffDuration(duration time.Duration) Option { - return func(o *priorityQueueOptions) { - o.podMaxBackoffDuration = duration - } -} - -// WithPodLister sets pod lister for PriorityQueue. -func WithPodLister(pl listersv1.PodLister) Option { - return func(o *priorityQueueOptions) { - o.podLister = pl - } -} - -// WithPodMaxInUnschedulablePodsDuration sets podMaxInUnschedulablePodsDuration for PriorityQueue. -func WithPodMaxInUnschedulablePodsDuration(duration time.Duration) Option { - return func(o *priorityQueueOptions) { - o.podMaxInUnschedulablePodsDuration = duration - } -} - -// QueueingHintMapPerProfile is keyed with profile name, valued with queueing hint map registered for the profile. -type QueueingHintMapPerProfile map[string]QueueingHintMap - -// QueueingHintMap is keyed with ClusterEvent, valued with queueing hint functions registered for the event. -type QueueingHintMap map[framework.ClusterEvent][]*QueueingHintFunction - -// WithQueueingHintMapPerProfile sets queueingHintMap for PriorityQueue. -func WithQueueingHintMapPerProfile(m QueueingHintMapPerProfile) Option { - return func(o *priorityQueueOptions) { - o.queueingHintMap = m - } -} - -// WithPreEnqueuePluginMap sets preEnqueuePluginMap for PriorityQueue. -func WithPreEnqueuePluginMap(m map[string][]framework.PreEnqueuePlugin) Option { - return func(o *priorityQueueOptions) { - o.preEnqueuePluginMap = m - } -} - -// WithMetricsRecorder sets metrics recorder. -func WithMetricsRecorder(recorder metrics.MetricAsyncRecorder) Option { - return func(o *priorityQueueOptions) { - o.metricsRecorder = recorder - } -} - -// WithPluginMetricsSamplePercent sets the percentage of plugin metrics to be sampled. -func WithPluginMetricsSamplePercent(percent int) Option { - return func(o *priorityQueueOptions) { - o.pluginMetricsSamplePercent = percent - } -} - -var defaultPriorityQueueOptions = priorityQueueOptions{ - clock: clock.RealClock{}, - podInitialBackoffDuration: DefaultPodInitialBackoffDuration, - podMaxBackoffDuration: DefaultPodMaxBackoffDuration, - podMaxInUnschedulablePodsDuration: DefaultPodMaxInUnschedulablePodsDuration, -} - -// Making sure that PriorityQueue implements SchedulingQueue. -var _ SchedulingQueue = &PriorityQueue{} - -// newQueuedPodInfoForLookup builds a QueuedPodInfo object for a lookup in the queue. -func newQueuedPodInfoForLookup(pod *v1.Pod, plugins ...string) *framework.QueuedPodInfo { - // Since this is only used for a lookup in the queue, we only need to set the Pod, - // and so we avoid creating a full PodInfo, which is expensive to instantiate frequently. - return &framework.QueuedPodInfo{ - PodInfo: &framework.PodInfo{Pod: pod}, - UnschedulablePlugins: sets.New(plugins...), - } -} - -// NewPriorityQueue creates a PriorityQueue object. -func NewPriorityQueue( - lessFn framework.LessFunc, - informerFactory informers.SharedInformerFactory, - opts ...Option, -) *PriorityQueue { - options := defaultPriorityQueueOptions - if options.podLister == nil { - options.podLister = informerFactory.Core().V1().Pods().Lister() - } - for _, opt := range opts { - opt(&options) - } - - isSchedulingQueueHintEnabled := utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) - isPopFromBackoffQEnabled := utilfeature.DefaultFeatureGate.Enabled(features.SchedulerPopFromBackoffQ) - - backoffQ := newBackoffQueue(options.clock, options.podInitialBackoffDuration, options.podMaxBackoffDuration, lessFn, isPopFromBackoffQEnabled) - pq := &PriorityQueue{ - clock: options.clock, - stop: make(chan struct{}), - podMaxInUnschedulablePodsDuration: options.podMaxInUnschedulablePodsDuration, - backoffQ: backoffQ, - unschedulablePods: newUnschedulablePods(metrics.NewUnschedulablePodsRecorder(), metrics.NewGatedPodsRecorder()), - preEnqueuePluginMap: options.preEnqueuePluginMap, - queueingHintMap: options.queueingHintMap, - metricsRecorder: options.metricsRecorder, - pluginMetricsSamplePercent: options.pluginMetricsSamplePercent, - moveRequestCycle: -1, - isSchedulingQueueHintEnabled: isSchedulingQueueHintEnabled, - isPopFromBackoffQEnabled: isPopFromBackoffQEnabled, - } - var backoffQPopper backoffQPopper - if isPopFromBackoffQEnabled { - backoffQPopper = backoffQ - } - pq.activeQ = newActiveQueue(heap.NewWithRecorder(podInfoKeyFunc, heap.LessFunc[*framework.QueuedPodInfo](lessFn), metrics.NewActivePodsRecorder()), isSchedulingQueueHintEnabled, options.metricsRecorder, backoffQPopper) - pq.nsLister = informerFactory.Core().V1().Namespaces().Lister() - pq.nominator = newPodNominator(options.podLister) - - return pq -} - -// Run starts the goroutine to pump from backoffQ to activeQ -func (p *PriorityQueue) Run(logger klog.Logger) { - go p.backoffQ.waitUntilAlignedWithOrderingWindow(func() { - p.flushBackoffQCompleted(logger) - }, p.stop) - go wait.Until(func() { - p.flushUnschedulablePodsLeftover(logger) - }, 30*time.Second, p.stop) -} - -// queueingStrategy indicates how the scheduling queue should enqueue the Pod from unschedulable pod pool. -type queueingStrategy int - -const ( - // queueSkip indicates that the scheduling queue should skip requeuing the Pod to activeQ/backoffQ. - queueSkip queueingStrategy = iota - // queueAfterBackoff indicates that the scheduling queue should requeue the Pod after backoff is completed. - queueAfterBackoff - // queueImmediately indicates that the scheduling queue should skip backoff and requeue the Pod immediately to activeQ. - queueImmediately -) - -// isEventOfInterest returns true if the event is of interest by some plugins. -func (p *PriorityQueue) isEventOfInterest(logger klog.Logger, event framework.ClusterEvent) bool { - if event.IsWildCard() { - // Wildcard event moves Pods that failed with any plugins. - return true - } - - for _, hintMap := range p.queueingHintMap { - for eventToMatch := range hintMap { - if eventToMatch.Match(event) { - // This event is interested by some plugins. - return true - } - } - } - - logger.V(6).Info("receive an event that isn't interested by any enabled plugins", "event", event) - - return false -} - -// isPodWorthRequeuing calls QueueingHintFn of only plugins registered in pInfo.unschedulablePlugins and pInfo.PendingPlugins. -// -// If any of pInfo.PendingPlugins return Queue, -// the scheduling queue is supposed to enqueue this Pod to activeQ, skipping backoffQ. -// If any of pInfo.unschedulablePlugins return Queue, -// the scheduling queue is supposed to enqueue this Pod to activeQ/backoffQ depending on the remaining backoff time of the Pod. -// If all QueueingHintFns returns Skip, the scheduling queue enqueues the Pod back to unschedulable Pod pool -// because no plugin changes the scheduling result via the event. -func (p *PriorityQueue) isPodWorthRequeuing(logger klog.Logger, pInfo *framework.QueuedPodInfo, event framework.ClusterEvent, oldObj, newObj interface{}) queueingStrategy { - rejectorPlugins := pInfo.UnschedulablePlugins.Union(pInfo.PendingPlugins) - if rejectorPlugins.Len() == 0 { - logger.V(6).Info("Worth requeuing because no failed plugins", "pod", klog.KObj(pInfo.Pod)) - return queueAfterBackoff - } - - if event.IsWildCard() { - // If the wildcard event has a Pod in newObj, - // that indicates that the event wants to be effective for the Pod only. - // Specifically, EventForceActivate could have a target Pod in newObj. - if newObj != nil { - if pod, ok := newObj.(*v1.Pod); !ok || pod.UID != pInfo.Pod.UID { - // This wildcard event is not for this Pod. - if ok { - logger.V(6).Info("Not worth requeuing because the event is wildcard, but for another pod", "pod", klog.KObj(pInfo.Pod), "event", event.Label(), "newObj", klog.KObj(pod)) - } - return queueSkip - } - } - - // If the wildcard event is special one as someone wants to force all Pods to move to activeQ/backoffQ. - // We return queueAfterBackoff in this case, while resetting all blocked plugins. - logger.V(6).Info("Worth requeuing because the event is wildcard", "pod", klog.KObj(pInfo.Pod), "event", event.Label()) - return queueAfterBackoff - } - - hintMap, ok := p.queueingHintMap[pInfo.Pod.Spec.SchedulerName] - if !ok { - // shouldn't reach here unless bug. - logger.Error(nil, "No QueueingHintMap is registered for this profile", "profile", pInfo.Pod.Spec.SchedulerName, "pod", klog.KObj(pInfo.Pod)) - return queueAfterBackoff - } - - pod := pInfo.Pod - queueStrategy := queueSkip - for eventToMatch, hintfns := range hintMap { - if !eventToMatch.Match(event) { - continue - } - - for _, hintfn := range hintfns { - if !rejectorPlugins.Has(hintfn.PluginName) { - // skip if it's not hintfn from rejectorPlugins. - continue - } - - start := time.Now() - hint, err := hintfn.QueueingHintFn(logger, pod, oldObj, newObj) - if err != nil { - // If the QueueingHintFn returned an error, we should treat the event as Queue so that we can prevent - // the Pod from being stuck in the unschedulable pod pool. - oldObjMeta, newObjMeta, asErr := util.As[klog.KMetadata](oldObj, newObj) - if asErr != nil { - logger.Error(err, "QueueingHintFn returns error", "event", event, "plugin", hintfn.PluginName, "pod", klog.KObj(pod)) - } else { - logger.Error(err, "QueueingHintFn returns error", "event", event, "plugin", hintfn.PluginName, "pod", klog.KObj(pod), "oldObj", klog.KObj(oldObjMeta), "newObj", klog.KObj(newObjMeta)) - } - hint = framework.Queue - } - p.metricsRecorder.ObserveQueueingHintDurationAsync(hintfn.PluginName, event.Label(), queueingHintToLabel(hint, err), metrics.SinceInSeconds(start)) - - if hint == framework.QueueSkip { - continue - } - - if pInfo.PendingPlugins.Has(hintfn.PluginName) { - // interprets Queue from the Pending plugin as queueImmediately. - // We can return immediately because queueImmediately is the highest priority. - return queueImmediately - } - - // interprets Queue from the unschedulable plugin as queueAfterBackoff. - - if pInfo.PendingPlugins.Len() == 0 { - // We can return immediately because no Pending plugins, which only can make queueImmediately, registered in this Pod, - // and queueAfterBackoff is the second highest priority. - return queueAfterBackoff - } - - // We can't return immediately because there are some Pending plugins registered in this Pod. - // We need to check if those plugins return Queue or not and if they do, we return queueImmediately. - queueStrategy = queueAfterBackoff - } - } - - return queueStrategy -} - -// queueingHintToLabel converts a hint and an error from QHint to a label string. -func queueingHintToLabel(hint framework.QueueingHint, err error) string { - if err != nil { - return metrics.QueueingHintResultError - } - - switch hint { - case framework.Queue: - return metrics.QueueingHintResultQueue - case framework.QueueSkip: - return metrics.QueueingHintResultQueueSkip - } - - // Shouldn't reach here. - return "" -} - -// runPreEnqueuePlugins iterates PreEnqueue function in each registered PreEnqueuePlugin. -// It returns true if all PreEnqueue function run successfully; otherwise returns false -// upon the first failure. -// Note: we need to associate the failed plugin to `pInfo`, so that the pod can be moved back -// to activeQ by related cluster event. -func (p *PriorityQueue) runPreEnqueuePlugins(ctx context.Context, pInfo *framework.QueuedPodInfo) bool { - logger := klog.FromContext(ctx) - var s *framework.Status - pod := pInfo.Pod - startTime := p.clock.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(preEnqueue, s.Code().String(), pod.Spec.SchedulerName).Observe(metrics.SinceInSeconds(startTime)) - }() - - shouldRecordMetric := rand.Intn(100) < p.pluginMetricsSamplePercent - for _, pl := range p.preEnqueuePluginMap[pod.Spec.SchedulerName] { - s = p.runPreEnqueuePlugin(ctx, pl, pod, shouldRecordMetric) - if s.IsSuccess() { - continue - } - pInfo.UnschedulablePlugins.Insert(pl.Name()) - metrics.UnschedulableReason(pl.Name(), pod.Spec.SchedulerName).Inc() - if s.Code() == framework.Error { - logger.Error(s.AsError(), "Unexpected error running PreEnqueue plugin", "pod", klog.KObj(pod), "plugin", pl.Name()) - } else { - logger.V(4).Info("Status after running PreEnqueue plugin", "pod", klog.KObj(pod), "plugin", pl.Name(), "status", s) - } - return false - } - return true -} - -func (p *PriorityQueue) runPreEnqueuePlugin(ctx context.Context, pl framework.PreEnqueuePlugin, pod *v1.Pod, shouldRecordMetric bool) *framework.Status { - if !shouldRecordMetric { - return pl.PreEnqueue(ctx, pod) - } - startTime := p.clock.Now() - s := pl.PreEnqueue(ctx, pod) - p.metricsRecorder.ObservePluginDurationAsync(preEnqueue, pl.Name(), s.Code().String(), p.clock.Since(startTime).Seconds()) - return s -} - -// moveToActiveQ tries to add the pod to the active queue. -// If the pod doesn't pass PreEnqueue plugins, it gets added to unschedulablePods instead. -// It returns a boolean flag to indicate whether the pod is added successfully. -func (p *PriorityQueue) moveToActiveQ(logger klog.Logger, pInfo *framework.QueuedPodInfo, event string) bool { - gatedBefore := pInfo.Gated - // If SchedulerPopFromBackoffQ feature gate is enabled, - // PreEnqueue plugins were called when the pod was added to the backoffQ. - // Don't need to repeat it here when the pod is directly moved from the backoffQ. - if !p.isPopFromBackoffQEnabled || event != framework.BackoffComplete { - pInfo.Gated = !p.runPreEnqueuePlugins(context.Background(), pInfo) - } - - added := false - p.activeQ.underLock(func(unlockedActiveQ unlockedActiveQueuer) { - if pInfo.Gated { - // Add the Pod to unschedulablePods if it's not passing PreEnqueuePlugins. - if unlockedActiveQ.has(pInfo) { - return - } - if p.backoffQ.has(pInfo) { - return - } - if p.unschedulablePods.get(pInfo.Pod) != nil { - return - } - p.unschedulablePods.addOrUpdate(pInfo, event) - logger.V(5).Info("Pod moved to an internal scheduling queue, because the pod is gated", "pod", klog.KObj(pInfo.Pod), "event", event, "queue", unschedulablePods) - return - } - if pInfo.InitialAttemptTimestamp == nil { - now := p.clock.Now() - pInfo.InitialAttemptTimestamp = &now - } - - unlockedActiveQ.add(pInfo, event) - added = true - - p.unschedulablePods.delete(pInfo.Pod, gatedBefore) - p.backoffQ.delete(pInfo) - logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pInfo.Pod), "event", event, "queue", activeQ) - if event == framework.EventUnscheduledPodAdd.Label() || event == framework.EventUnscheduledPodUpdate.Label() { - p.AddNominatedPod(logger, pInfo.PodInfo, nil) - } - }) - return added -} - -// moveToBackoffQ tries to add the pod to the backoff queue. -// If SchedulerPopFromBackoffQ feature gate is enabled and the pod doesn't pass PreEnqueue plugins, it gets added to unschedulablePods instead. -// It returns a boolean flag to indicate whether the pod is added successfully. -func (p *PriorityQueue) moveToBackoffQ(logger klog.Logger, pInfo *framework.QueuedPodInfo, event string) bool { - // If SchedulerPopFromBackoffQ feature gate is enabled, - // PreEnqueue plugins are called on inserting pods to the backoffQ, - // not to call them again on popping out. - if p.isPopFromBackoffQEnabled { - pInfo.Gated = !p.runPreEnqueuePlugins(context.Background(), pInfo) - if pInfo.Gated { - if p.unschedulablePods.get(pInfo.Pod) == nil { - p.unschedulablePods.addOrUpdate(pInfo, event) - logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pInfo.Pod), "event", event, "queue", unschedulablePods) - } - return false - } - } - p.backoffQ.add(logger, pInfo, event) - logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pInfo.Pod), "event", event, "queue", backoffQ) - return true -} - -// Add adds a pod to the active queue. It should be called only when a new pod -// is added so there is no chance the pod is already in active/unschedulable/backoff queues -func (p *PriorityQueue) Add(logger klog.Logger, pod *v1.Pod) { - p.lock.Lock() - defer p.lock.Unlock() - - pInfo := p.newQueuedPodInfo(pod) - if added := p.moveToActiveQ(logger, pInfo, framework.EventUnscheduledPodAdd.Label()); added { - p.activeQ.broadcast() - } -} - -// Activate moves the given pods to activeQ. -// If a pod isn't found in unschedulablePods or backoffQ and it's in-flight, -// the wildcard event is registered so that the pod will be requeued when it comes back. -// But, if a pod isn't found in unschedulablePods or backoffQ and it's not in-flight (i.e., completely unknown pod), -// Activate would ignore the pod. -func (p *PriorityQueue) Activate(logger klog.Logger, pods map[string]*v1.Pod) { - p.lock.Lock() - defer p.lock.Unlock() - - activated := false - for _, pod := range pods { - if p.activate(logger, pod) { - activated = true - continue - } - - // If this pod is in-flight, register the activation event (for when QHint is enabled) or update moveRequestCycle (for when QHints is disabled) - // so that the pod will be requeued when it comes back. - // Specifically in the in-tree plugins, this is for the scenario with the preemption plugin - // where the async preemption API calls are all done or fail at some point before the Pod comes back to the queue. - p.activeQ.addEventsIfPodInFlight(nil, pod, []framework.ClusterEvent{framework.EventForceActivate}) - p.moveRequestCycle = p.activeQ.schedulingCycle() - } - - if activated { - p.activeQ.broadcast() - } -} - -func (p *PriorityQueue) activate(logger klog.Logger, pod *v1.Pod) bool { - var pInfo *framework.QueuedPodInfo - // Verify if the pod is present in unschedulablePods or backoffQ. - if pInfo = p.unschedulablePods.get(pod); pInfo == nil { - // If the pod doesn't belong to unschedulablePods or backoffQ, don't activate it. - // The pod can be already in activeQ. - var exists bool - pInfo, exists = p.backoffQ.get(newQueuedPodInfoForLookup(pod)) - if !exists { - return false - } - // Delete pod from the backoffQ now to make sure it won't be popped from the backoffQ - // just before moving it to the activeQ - if deleted := p.backoffQ.delete(pInfo); !deleted { - // Pod was popped from the backoffQ in the meantime. Don't activate it. - return false - } - } - - if pInfo == nil { - // Redundant safe check. We shouldn't reach here. - logger.Error(nil, "Internal error: cannot obtain pInfo") - return false - } - - return p.moveToActiveQ(logger, pInfo, framework.ForceActivate) -} - -// SchedulingCycle returns current scheduling cycle. -func (p *PriorityQueue) SchedulingCycle() int64 { - return p.activeQ.schedulingCycle() -} - -// determineSchedulingHintForInFlightPod looks at the unschedulable plugins of the given Pod -// and determines the scheduling hint for this Pod while checking the events that happened during in-flight. -func (p *PriorityQueue) determineSchedulingHintForInFlightPod(logger klog.Logger, pInfo *framework.QueuedPodInfo) queueingStrategy { - if len(pInfo.UnschedulablePlugins) == 0 && len(pInfo.PendingPlugins) == 0 { - // No failed plugins are associated with this Pod. - // Meaning something unusual (a temporal failure on kube-apiserver, etc) happened and this Pod gets moved back to the queue. - // In this case, we should retry scheduling it because this Pod may not be retried until the next flush. - return queueAfterBackoff - } - - events, err := p.activeQ.clusterEventsForPod(logger, pInfo) - if err != nil { - logger.Error(err, "Error getting cluster events for pod", "pod", klog.KObj(pInfo.Pod)) - return queueAfterBackoff - } - - // check if there is an event that makes this Pod schedulable based on pInfo.UnschedulablePlugins. - queueingStrategy := queueSkip - for _, e := range events { - logger.V(5).Info("Checking event for in-flight pod", "pod", klog.KObj(pInfo.Pod), "event", e.event.Label()) - - switch p.isPodWorthRequeuing(logger, pInfo, e.event, e.oldObj, e.newObj) { - case queueSkip: - continue - case queueImmediately: - // queueImmediately is the highest priority. - // No need to go through the rest of the events. - return queueImmediately - case queueAfterBackoff: - // replace schedulingHint with queueAfterBackoff - queueingStrategy = queueAfterBackoff - if pInfo.PendingPlugins.Len() == 0 { - // We can return immediately because no Pending plugins, which only can make queueImmediately, registered in this Pod, - // and queueAfterBackoff is the second highest priority. - return queueAfterBackoff - } - } - } - return queueingStrategy -} - -// addUnschedulableIfNotPresentWithoutQueueingHint inserts a pod that cannot be scheduled into -// the queue, unless it is already in the queue. Normally, PriorityQueue puts -// unschedulable pods in `unschedulablePods`. But if there has been a recent move -// request, then the pod is put in `backoffQ`. -// TODO: This function is called only when p.isSchedulingQueueHintEnabled is false, -// and this will be removed after SchedulingQueueHint goes to stable and the feature gate is removed. -func (p *PriorityQueue) addUnschedulableWithoutQueueingHint(logger klog.Logger, pInfo *framework.QueuedPodInfo, podSchedulingCycle int64) error { - pod := pInfo.Pod - // Refresh the timestamp since the pod is re-added. - pInfo.Timestamp = p.clock.Now() - - // When the queueing hint is enabled, they are used differently. - // But, we use all of them as UnschedulablePlugins when the queueing hint isn't enabled so that we don't break the old behaviour. - rejectorPlugins := pInfo.UnschedulablePlugins.Union(pInfo.PendingPlugins) - - // If a move request has been received, move it to the BackoffQ, otherwise move - // it to unschedulablePods. - for plugin := range rejectorPlugins { - metrics.UnschedulableReason(plugin, pInfo.Pod.Spec.SchedulerName).Inc() - } - if p.moveRequestCycle >= podSchedulingCycle || len(rejectorPlugins) == 0 { - // Two cases to move a Pod to the active/backoff queue: - // - The Pod is rejected by some plugins, but a move request is received after this Pod's scheduling cycle is started. - // In this case, the received event may be make Pod schedulable and we should retry scheduling it. - // - No unschedulable plugins are associated with this Pod, - // meaning something unusual (a temporal failure on kube-apiserver, etc) happened and this Pod gets moved back to the queue. - // In this case, we should retry scheduling it because this Pod may not be retried until the next flush. - if added := p.moveToBackoffQ(logger, pInfo, framework.ScheduleAttemptFailure); added { - if p.isPopFromBackoffQEnabled { - p.activeQ.broadcast() - } - } - } else { - p.unschedulablePods.addOrUpdate(pInfo, framework.ScheduleAttemptFailure) - logger.V(5).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pod), "event", framework.ScheduleAttemptFailure, "queue", unschedulablePods) - } - - return nil -} - -// AddUnschedulableIfNotPresent inserts a pod that cannot be scheduled into -// the queue, unless it is already in the queue. Normally, PriorityQueue puts -// unschedulable pods in `unschedulablePods`. But if there has been a recent move -// request, then the pod is put in `backoffQ`. -func (p *PriorityQueue) AddUnschedulableIfNotPresent(logger klog.Logger, pInfo *framework.QueuedPodInfo, podSchedulingCycle int64) error { - p.lock.Lock() - defer p.lock.Unlock() - - // In any case, this Pod will be moved back to the queue and we should call Done. - defer p.Done(pInfo.Pod.UID) - - pod := pInfo.Pod - if p.unschedulablePods.get(pod) != nil { - return fmt.Errorf("Pod %v is already present in unschedulable queue", klog.KObj(pod)) - } - - if p.activeQ.has(pInfo) { - return fmt.Errorf("Pod %v is already present in the active queue", klog.KObj(pod)) - } - if p.backoffQ.has(pInfo) { - return fmt.Errorf("Pod %v is already present in the backoff queue", klog.KObj(pod)) - } - - if !p.isSchedulingQueueHintEnabled { - // fall back to the old behavior which doesn't depend on the queueing hint. - return p.addUnschedulableWithoutQueueingHint(logger, pInfo, podSchedulingCycle) - } - - // Refresh the timestamp since the pod is re-added. - pInfo.Timestamp = p.clock.Now() - - // If a move request has been received, move it to the BackoffQ, otherwise move - // it to unschedulablePods. - rejectorPlugins := pInfo.UnschedulablePlugins.Union(pInfo.PendingPlugins) - for plugin := range rejectorPlugins { - metrics.UnschedulableReason(plugin, pInfo.Pod.Spec.SchedulerName).Inc() - } - - // We check whether this Pod may change its scheduling result by any of events that happened during scheduling. - schedulingHint := p.determineSchedulingHintForInFlightPod(logger, pInfo) - - // In this case, we try to requeue this Pod to activeQ/backoffQ. - queue := p.requeuePodViaQueueingHint(logger, pInfo, schedulingHint, framework.ScheduleAttemptFailure) - logger.V(3).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pod), "event", framework.ScheduleAttemptFailure, "queue", queue, "schedulingCycle", podSchedulingCycle, "hint", schedulingHint, "unschedulable plugins", rejectorPlugins) - if queue == activeQ || (p.isPopFromBackoffQEnabled && queue == backoffQ) { - // When the Pod is moved to activeQ, need to let p.cond know so that the Pod will be pop()ed out. - p.activeQ.broadcast() - } - - return nil -} - -// flushBackoffQCompleted Moves all pods from backoffQ which have completed backoff in to activeQ -func (p *PriorityQueue) flushBackoffQCompleted(logger klog.Logger) { - p.lock.Lock() - defer p.lock.Unlock() - activated := false - podsCompletedBackoff := p.backoffQ.popAllBackoffCompleted(logger) - for _, pInfo := range podsCompletedBackoff { - if added := p.moveToActiveQ(logger, pInfo, framework.BackoffComplete); added { - activated = true - } - } - if activated { - p.activeQ.broadcast() - } -} - -// flushUnschedulablePodsLeftover moves pods which stay in unschedulablePods -// longer than podMaxInUnschedulablePodsDuration to backoffQ or activeQ. -func (p *PriorityQueue) flushUnschedulablePodsLeftover(logger klog.Logger) { - p.lock.Lock() - defer p.lock.Unlock() - - var podsToMove []*framework.QueuedPodInfo - currentTime := p.clock.Now() - for _, pInfo := range p.unschedulablePods.podInfoMap { - lastScheduleTime := pInfo.Timestamp - if currentTime.Sub(lastScheduleTime) > p.podMaxInUnschedulablePodsDuration { - podsToMove = append(podsToMove, pInfo) - } - } - - if len(podsToMove) > 0 { - p.movePodsToActiveOrBackoffQueue(logger, podsToMove, framework.EventUnschedulableTimeout, nil, nil) - } -} - -// Pop removes the head of the active queue and returns it. It blocks if the -// activeQ is empty and waits until a new item is added to the queue. It -// increments scheduling cycle when a pod is popped. -// Note: This method should NOT be locked by the p.lock at any moment, -// as it would lead to scheduling throughput degradation. -func (p *PriorityQueue) Pop(logger klog.Logger) (*framework.QueuedPodInfo, error) { - return p.activeQ.pop(logger) -} - -// Done must be called for pod returned by Pop. This allows the queue to -// keep track of which pods are currently being processed. -func (p *PriorityQueue) Done(pod types.UID) { - if !p.isSchedulingQueueHintEnabled { - // do nothing if schedulingQueueHint is disabled. - // In that case, we don't have inFlightPods and inFlightEvents. - return - } - p.activeQ.done(pod) -} - -func (p *PriorityQueue) InFlightPods() []*v1.Pod { - if !p.isSchedulingQueueHintEnabled { - // do nothing if schedulingQueueHint is disabled. - // In that case, we don't have inFlightPods and inFlightEvents. - return nil - } - return p.activeQ.listInFlightPods() -} - -// isPodUpdated checks if the pod is updated in a way that it may have become -// schedulable. It drops status of the pod and compares it with old version, -// except for pod.status.resourceClaimStatuses: changing that may have an -// effect on scheduling. -func isPodUpdated(oldPod, newPod *v1.Pod) bool { - strip := func(pod *v1.Pod) *v1.Pod { - p := pod.DeepCopy() - p.ResourceVersion = "" - p.Generation = 0 - p.Status = v1.PodStatus{ - ResourceClaimStatuses: pod.Status.ResourceClaimStatuses, - } - p.ManagedFields = nil - p.Finalizers = nil - return p - } - return !reflect.DeepEqual(strip(oldPod), strip(newPod)) -} - -// Update updates a pod in the active or backoff queue if present. Otherwise, it removes -// the item from the unschedulable queue if pod is updated in a way that it may -// become schedulable and adds the updated one to the active queue. -// If pod is not present in any of the queues, it is added to the active queue. -func (p *PriorityQueue) Update(logger klog.Logger, oldPod, newPod *v1.Pod) { - p.lock.Lock() - defer p.lock.Unlock() - - var events []framework.ClusterEvent - if p.isSchedulingQueueHintEnabled { - events = framework.PodSchedulingPropertiesChange(newPod, oldPod) - // The inflight pod will be requeued using the latest version from the informer cache, which matches what the event delivers. - // Record this Pod update because - // this update may make the Pod schedulable in case it gets rejected and comes back to the queue. - // We can clean it up once we change updatePodInSchedulingQueue to call MoveAllToActiveOrBackoffQueue. - // See https://github.com/kubernetes/kubernetes/pull/125578#discussion_r1648338033 for more context. - if exists := p.activeQ.addEventsIfPodInFlight(oldPod, newPod, events); exists { - logger.V(6).Info("The pod doesn't be queued for now because it's being scheduled and will be queued back if necessary", "pod", klog.KObj(newPod)) - return - } - } - - if oldPod != nil { - oldPodInfo := newQueuedPodInfoForLookup(oldPod) - // If the pod is already in the active queue, just update it there. - if pInfo := p.activeQ.update(newPod, oldPodInfo); pInfo != nil { - p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo) - return - } - - // If the pod is in the backoff queue, update it there. - if pInfo := p.backoffQ.update(newPod, oldPodInfo); pInfo != nil { - p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo) - return - } - } - - // If the pod is in the unschedulable queue, updating it may make it schedulable. - if pInfo := p.unschedulablePods.get(newPod); pInfo != nil { - _ = pInfo.Update(newPod) - p.UpdateNominatedPod(logger, oldPod, pInfo.PodInfo) - gated := pInfo.Gated - if p.isSchedulingQueueHintEnabled { - // When unscheduled Pods are updated, we check with QueueingHint - // whether the update may make the pods schedulable. - // Plugins have to implement a QueueingHint for Pod/Update event - // if the rejection from them could be resolved by updating unscheduled Pods itself. - for _, evt := range events { - hint := p.isPodWorthRequeuing(logger, pInfo, evt, oldPod, newPod) - queue := p.requeuePodViaQueueingHint(logger, pInfo, hint, evt.Label()) - if queue != unschedulablePods { - logger.V(5).Info("Pod moved to an internal scheduling queue because the Pod is updated", "pod", klog.KObj(newPod), "event", evt.Label(), "queue", queue) - p.unschedulablePods.delete(pInfo.Pod, gated) - } - if queue == activeQ || (p.isPopFromBackoffQEnabled && queue == backoffQ) { - p.activeQ.broadcast() - break - } - } - return - } - if isPodUpdated(oldPod, newPod) { - // Pod might have completed its backoff time while being in unschedulablePods, - // so we should check isPodBackingoff before moving the pod to backoffQ. - if p.backoffQ.isPodBackingoff(pInfo) { - if added := p.moveToBackoffQ(logger, pInfo, framework.EventUnscheduledPodUpdate.Label()); added { - p.unschedulablePods.delete(pInfo.Pod, gated) - if p.isPopFromBackoffQEnabled { - p.activeQ.broadcast() - } - } - return - } - - if added := p.moveToActiveQ(logger, pInfo, framework.EventUnscheduledPodUpdate.Label()); added { - p.activeQ.broadcast() - } - return - } - - // Pod update didn't make it schedulable, keep it in the unschedulable queue. - p.unschedulablePods.addOrUpdate(pInfo, framework.EventUnscheduledPodUpdate.Label()) - return - } - // If pod is not in any of the queues, we put it in the active queue. - pInfo := p.newQueuedPodInfo(newPod) - if added := p.moveToActiveQ(logger, pInfo, framework.EventUnscheduledPodUpdate.Label()); added { - p.activeQ.broadcast() - } -} - -// Delete deletes the item from either of the two queues. It assumes the pod is -// only in one queue. -func (p *PriorityQueue) Delete(pod *v1.Pod) { - p.lock.Lock() - defer p.lock.Unlock() - p.DeleteNominatedPodIfExists(pod) - pInfo := newQueuedPodInfoForLookup(pod) - if err := p.activeQ.delete(pInfo); err == nil { - return - } - if deleted := p.backoffQ.delete(pInfo); deleted { - return - } - if pInfo = p.unschedulablePods.get(pod); pInfo != nil { - p.unschedulablePods.delete(pod, pInfo.Gated) - } -} - -// AssignedPodAdded is called when a bound pod is added. Creation of this pod -// may make pending pods with matching affinity terms schedulable. -func (p *PriorityQueue) AssignedPodAdded(logger klog.Logger, pod *v1.Pod) { - p.lock.Lock() - - // Pre-filter Pods to move by getUnschedulablePodsWithCrossTopologyTerm - // because Pod related events shouldn't make Pods that rejected by single-node scheduling requirement schedulable. - p.movePodsToActiveOrBackoffQueue(logger, p.getUnschedulablePodsWithCrossTopologyTerm(logger, pod), framework.EventAssignedPodAdd, nil, pod) - p.lock.Unlock() -} - -// AssignedPodUpdated is called when a bound pod is updated. Change of labels -// may make pending pods with matching affinity terms schedulable. -func (p *PriorityQueue) AssignedPodUpdated(logger klog.Logger, oldPod, newPod *v1.Pod, event framework.ClusterEvent) { - p.lock.Lock() - if (framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.UpdatePodScaleDown}.Match(event)) { - // In this case, we don't want to pre-filter Pods by getUnschedulablePodsWithCrossTopologyTerm - // because Pod related events may make Pods that were rejected by NodeResourceFit schedulable. - p.moveAllToActiveOrBackoffQueue(logger, event, oldPod, newPod, nil) - } else { - // Pre-filter Pods to move by getUnschedulablePodsWithCrossTopologyTerm - // because Pod related events only make Pods rejected by cross topology term schedulable. - p.movePodsToActiveOrBackoffQueue(logger, p.getUnschedulablePodsWithCrossTopologyTerm(logger, newPod), event, oldPod, newPod) - } - p.lock.Unlock() -} - -// NOTE: this function assumes a lock has been acquired in the caller. -// moveAllToActiveOrBackoffQueue moves all pods from unschedulablePods to activeQ or backoffQ. -// This function adds all pods and then signals the condition variable to ensure that -// if Pop() is waiting for an item, it receives the signal after all the pods are in the -// queue and the head is the highest priority pod. -func (p *PriorityQueue) moveAllToActiveOrBackoffQueue(logger klog.Logger, event framework.ClusterEvent, oldObj, newObj interface{}, preCheck PreEnqueueCheck) { - if !p.isEventOfInterest(logger, event) { - // No plugin is interested in this event. - // Return early before iterating all pods in unschedulablePods for preCheck. - return - } - - unschedulablePods := make([]*framework.QueuedPodInfo, 0, len(p.unschedulablePods.podInfoMap)) - for _, pInfo := range p.unschedulablePods.podInfoMap { - if preCheck == nil || preCheck(pInfo.Pod) { - unschedulablePods = append(unschedulablePods, pInfo) - } - } - p.movePodsToActiveOrBackoffQueue(logger, unschedulablePods, event, oldObj, newObj) -} - -// MoveAllToActiveOrBackoffQueue moves all pods from unschedulablePods to activeQ or backoffQ. -// This function adds all pods and then signals the condition variable to ensure that -// if Pop() is waiting for an item, it receives the signal after all the pods are in the -// queue and the head is the highest priority pod. -func (p *PriorityQueue) MoveAllToActiveOrBackoffQueue(logger klog.Logger, event framework.ClusterEvent, oldObj, newObj interface{}, preCheck PreEnqueueCheck) { - p.lock.Lock() - defer p.lock.Unlock() - p.moveAllToActiveOrBackoffQueue(logger, event, oldObj, newObj, preCheck) -} - -// requeuePodViaQueueingHint tries to requeue Pod to activeQ, backoffQ or unschedulable pod pool based on schedulingHint. -// It returns the queue name Pod goes. -// -// NOTE: this function assumes lock has been acquired in caller -func (p *PriorityQueue) requeuePodViaQueueingHint(logger klog.Logger, pInfo *framework.QueuedPodInfo, strategy queueingStrategy, event string) string { - if strategy == queueSkip { - p.unschedulablePods.addOrUpdate(pInfo, event) - return unschedulablePods - } - - // Pod might have completed its backoff time while being in unschedulablePods, - // so we should check isPodBackingoff before moving the pod to backoffQ. - if strategy == queueAfterBackoff && p.backoffQ.isPodBackingoff(pInfo) { - if added := p.moveToBackoffQ(logger, pInfo, event); added { - return backoffQ - } - return unschedulablePods - } - - // Reach here if schedulingHint is QueueImmediately, or schedulingHint is Queue but the pod is not backing off. - if added := p.moveToActiveQ(logger, pInfo, event); added { - return activeQ - } - // Pod is gated. We don't have to push it back to unschedulable queue, because moveToActiveQ should already have done that. - return unschedulablePods -} - -// NOTE: this function assumes lock has been acquired in caller -func (p *PriorityQueue) movePodsToActiveOrBackoffQueue(logger klog.Logger, podInfoList []*framework.QueuedPodInfo, event framework.ClusterEvent, oldObj, newObj interface{}) { - if !p.isEventOfInterest(logger, event) { - // No plugin is interested in this event. - return - } - - activated := false - for _, pInfo := range podInfoList { - // When handling events takes time, a scheduling throughput gets impacted negatively - // because of a shared lock within PriorityQueue, which Pop() also requires. - // - // Scheduling-gated Pods never get schedulable with any events, - // except the Pods themselves got updated, which isn't handled by movePodsToActiveOrBackoffQueue. - // So, we can skip them early here so that they don't go through isPodWorthRequeuing, - // which isn't fast enough to keep a sufficient scheduling throughput - // when the number of scheduling-gated Pods in unschedulablePods is large. - // https://github.com/kubernetes/kubernetes/issues/124384 - // This is a hotfix for this issue, which might be changed - // once we have a better general solution for the shared lock issue. - // - // Note that we cannot skip all pInfo.Gated Pods here - // because PreEnqueue plugins apart from the scheduling gate plugin may change the gating status - // with these events. - if pInfo.Gated && pInfo.UnschedulablePlugins.Has(names.SchedulingGates) { - continue - } - - schedulingHint := p.isPodWorthRequeuing(logger, pInfo, event, oldObj, newObj) - if schedulingHint == queueSkip { - // QueueingHintFn determined that this Pod isn't worth putting to activeQ or backoffQ by this event. - logger.V(5).Info("Event is not making pod schedulable", "pod", klog.KObj(pInfo.Pod), "event", event.Label()) - continue - } - - p.unschedulablePods.delete(pInfo.Pod, pInfo.Gated) - queue := p.requeuePodViaQueueingHint(logger, pInfo, schedulingHint, event.Label()) - logger.V(4).Info("Pod moved to an internal scheduling queue", "pod", klog.KObj(pInfo.Pod), "event", event.Label(), "queue", queue, "hint", schedulingHint) - if queue == activeQ || (p.isPopFromBackoffQEnabled && queue == backoffQ) { - activated = true - } - } - - p.moveRequestCycle = p.activeQ.schedulingCycle() - - if p.isSchedulingQueueHintEnabled { - // AddUnschedulableIfNotPresent might get called for in-flight Pods later, and in - // AddUnschedulableIfNotPresent we need to know whether events were - // observed while scheduling them. - if added := p.activeQ.addEventIfAnyInFlight(oldObj, newObj, event); added { - logger.V(5).Info("Event received while pods are in flight", "event", event.Label()) - } - } - - if activated { - p.activeQ.broadcast() - } -} - -// getUnschedulablePodsWithCrossTopologyTerm returns unschedulable pods which either of following conditions is met: -// - have any affinity term that matches "pod". -// - rejected by PodTopologySpread plugin. -// NOTE: this function assumes lock has been acquired in caller. -func (p *PriorityQueue) getUnschedulablePodsWithCrossTopologyTerm(logger klog.Logger, pod *v1.Pod) []*framework.QueuedPodInfo { - nsLabels := interpodaffinity.GetNamespaceLabelsSnapshot(logger, pod.Namespace, p.nsLister) - - var podsToMove []*framework.QueuedPodInfo - for _, pInfo := range p.unschedulablePods.podInfoMap { - if pInfo.UnschedulablePlugins.Has(podtopologyspread.Name) && pod.Namespace == pInfo.Pod.Namespace { - // This Pod may be schedulable now by this Pod event. - podsToMove = append(podsToMove, pInfo) - continue - } - - for _, term := range pInfo.RequiredAffinityTerms { - if term.Matches(pod, nsLabels) { - podsToMove = append(podsToMove, pInfo) - break - } - } - } - - return podsToMove -} - -// PodsInActiveQ returns all the Pods in the activeQ. -func (p *PriorityQueue) PodsInActiveQ() []*v1.Pod { - return p.activeQ.list() -} - -// PodsInBackoffQ returns all the Pods in the backoffQ. -func (p *PriorityQueue) PodsInBackoffQ() []*v1.Pod { - return p.backoffQ.list() -} - -// UnschedulablePods returns all the pods in unschedulable state. -func (p *PriorityQueue) UnschedulablePods() []*v1.Pod { - var result []*v1.Pod - for _, pInfo := range p.unschedulablePods.podInfoMap { - result = append(result, pInfo.Pod) - } - return result -} - -var pendingPodsSummary = "activeQ:%v; backoffQ:%v; unschedulablePods:%v" - -// GetPod searches for a pod in the activeQ, backoffQ, and unschedulablePods. -func (p *PriorityQueue) GetPod(name, namespace string) (pInfo *framework.QueuedPodInfo, ok bool) { - p.lock.RLock() - defer p.lock.RUnlock() - - pInfoLookup := &framework.QueuedPodInfo{ - PodInfo: &framework.PodInfo{ - Pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: namespace, - }, - }, - }, - } - if pInfo, ok = p.backoffQ.get(pInfoLookup); ok { - return pInfo, true - } - if pInfo = p.unschedulablePods.get(pInfoLookup.Pod); pInfo != nil { - return pInfo, true - } - - p.activeQ.underRLock(func(unlockedActiveQ unlockedActiveQueueReader) { - pInfo, ok = unlockedActiveQ.get(pInfoLookup) - }) - return -} - -// PendingPods returns all the pending pods in the queue; accompanied by a debugging string -// recording showing the number of pods in each queue respectively. -// This function is used for debugging purposes in the scheduler cache dumper and comparer. -func (p *PriorityQueue) PendingPods() ([]*v1.Pod, string) { - p.lock.RLock() - defer p.lock.RUnlock() - result := p.PodsInActiveQ() - activeQLen := len(result) - backoffQPods := p.PodsInBackoffQ() - backoffQLen := len(backoffQPods) - result = append(result, backoffQPods...) - for _, pInfo := range p.unschedulablePods.podInfoMap { - result = append(result, pInfo.Pod) - } - return result, fmt.Sprintf(pendingPodsSummary, activeQLen, backoffQLen, len(p.unschedulablePods.podInfoMap)) -} - -// Note: this function assumes the caller locks both p.lock.RLock and p.activeQ.getLock().RLock. -func (p *PriorityQueue) nominatedPodToInfo(np podRef, unlockedActiveQ unlockedActiveQueueReader) *framework.PodInfo { - pod := np.toPod() - pInfoLookup := newQueuedPodInfoForLookup(pod) - - queuedPodInfo, exists := unlockedActiveQ.get(pInfoLookup) - if exists { - return queuedPodInfo.PodInfo - } - - queuedPodInfo = p.unschedulablePods.get(pod) - if queuedPodInfo != nil { - return queuedPodInfo.PodInfo - } - - queuedPodInfo, exists = p.backoffQ.get(pInfoLookup) - if exists { - return queuedPodInfo.PodInfo - } - - return &framework.PodInfo{Pod: pod} -} - -// Close closes the priority queue. -func (p *PriorityQueue) Close() { - p.lock.Lock() - defer p.lock.Unlock() - close(p.stop) - p.activeQ.close() - p.activeQ.broadcast() -} - -// NominatedPodsForNode returns a copy of pods that are nominated to run on the given node, -// but they are waiting for other pods to be removed from the node. -// CAUTION: Make sure you don't call this function while taking any queue's lock in any scenario. -func (p *PriorityQueue) NominatedPodsForNode(nodeName string) []*framework.PodInfo { - p.lock.RLock() - defer p.lock.RUnlock() - nominatedPods := p.nominator.nominatedPodsForNode(nodeName) - - pods := make([]*framework.PodInfo, len(nominatedPods)) - p.activeQ.underRLock(func(unlockedActiveQ unlockedActiveQueueReader) { - for i, np := range nominatedPods { - pods[i] = p.nominatedPodToInfo(np, unlockedActiveQ).DeepCopy() - } - }) - return pods -} - -// newQueuedPodInfo builds a QueuedPodInfo object. -func (p *PriorityQueue) newQueuedPodInfo(pod *v1.Pod, plugins ...string) *framework.QueuedPodInfo { - now := p.clock.Now() - // ignore this err since apiserver doesn't properly validate affinity terms - // and we can't fix the validation for backwards compatibility. - podInfo, _ := framework.NewPodInfo(pod) - return &framework.QueuedPodInfo{ - PodInfo: podInfo, - Timestamp: now, - InitialAttemptTimestamp: nil, - UnschedulablePlugins: sets.New(plugins...), - } -} - -// UnschedulablePods holds pods that cannot be scheduled. This data structure -// is used to implement unschedulablePods. -type UnschedulablePods struct { - // podInfoMap is a map key by a pod's full-name and the value is a pointer to the QueuedPodInfo. - podInfoMap map[string]*framework.QueuedPodInfo - keyFunc func(*v1.Pod) string - // unschedulableRecorder/gatedRecorder updates the counter when elements of an unschedulablePodsMap - // get added or removed, and it does nothing if it's nil. - unschedulableRecorder, gatedRecorder metrics.MetricRecorder -} - -// addOrUpdate adds a pod to the unschedulable podInfoMap. -// The event should show which event triggered the addition and is used for the metric recording. -func (u *UnschedulablePods) addOrUpdate(pInfo *framework.QueuedPodInfo, event string) { - podID := u.keyFunc(pInfo.Pod) - if _, exists := u.podInfoMap[podID]; !exists { - if pInfo.Gated && u.gatedRecorder != nil { - u.gatedRecorder.Inc() - } else if !pInfo.Gated && u.unschedulableRecorder != nil { - u.unschedulableRecorder.Inc() - } - metrics.SchedulerQueueIncomingPods.WithLabelValues("unschedulable", event).Inc() - } - u.podInfoMap[podID] = pInfo -} - -// delete deletes a pod from the unschedulable podInfoMap. -// The `gated` parameter is used to figure out which metric should be decreased. -func (u *UnschedulablePods) delete(pod *v1.Pod, gated bool) { - podID := u.keyFunc(pod) - if _, exists := u.podInfoMap[podID]; exists { - if gated && u.gatedRecorder != nil { - u.gatedRecorder.Dec() - } else if !gated && u.unschedulableRecorder != nil { - u.unschedulableRecorder.Dec() - } - } - delete(u.podInfoMap, podID) -} - -// get returns the QueuedPodInfo if a pod with the same key as the key of the given "pod" -// is found in the map. It returns nil otherwise. -func (u *UnschedulablePods) get(pod *v1.Pod) *framework.QueuedPodInfo { - podKey := u.keyFunc(pod) - if pInfo, exists := u.podInfoMap[podKey]; exists { - return pInfo - } - return nil -} - -// clear removes all the entries from the unschedulable podInfoMap. -func (u *UnschedulablePods) clear() { - u.podInfoMap = make(map[string]*framework.QueuedPodInfo) - if u.unschedulableRecorder != nil { - u.unschedulableRecorder.Clear() - } - if u.gatedRecorder != nil { - u.gatedRecorder.Clear() - } -} - -// newUnschedulablePods initializes a new object of UnschedulablePods. -func newUnschedulablePods(unschedulableRecorder, gatedRecorder metrics.MetricRecorder) *UnschedulablePods { - return &UnschedulablePods{ - podInfoMap: make(map[string]*framework.QueuedPodInfo), - keyFunc: util.GetPodFullName, - unschedulableRecorder: unschedulableRecorder, - gatedRecorder: gatedRecorder, - } -} - -func podInfoKeyFunc(pInfo *framework.QueuedPodInfo) string { - return cache.NewObjectName(pInfo.Pod.Namespace, pInfo.Pod.Name).String() -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/testing.go b/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/testing.go deleted file mode 100644 index f619bac84..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/backend/queue/testing.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package queue - -import ( - "context" - "time" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/informers" - "k8s.io/client-go/kubernetes/fake" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/metrics" -) - -// NewTestQueue creates a priority queue with an empty informer factory. -func NewTestQueue(ctx context.Context, lessFn framework.LessFunc, opts ...Option) *PriorityQueue { - return NewTestQueueWithObjects(ctx, lessFn, nil, opts...) -} - -// NewTestQueueWithObjects creates a priority queue with an informer factory -// populated with the provided objects. -func NewTestQueueWithObjects( - ctx context.Context, - lessFn framework.LessFunc, - objs []runtime.Object, - opts ...Option, -) *PriorityQueue { - informerFactory := informers.NewSharedInformerFactory(fake.NewClientset(objs...), 0) - - // Because some major functions (e.g., Pop) requires the metric recorder to be set, - // we always set a metric recorder here. - recorder := metrics.NewMetricsAsyncRecorder(10, 20*time.Microsecond, ctx.Done()) - // We set it before the options that users provide, so that users can override it. - opts = append([]Option{WithMetricsRecorder(*recorder)}, opts...) - return NewTestQueueWithInformerFactory(ctx, lessFn, informerFactory, opts...) -} - -func NewTestQueueWithInformerFactory( - ctx context.Context, - lessFn framework.LessFunc, - informerFactory informers.SharedInformerFactory, - opts ...Option, -) *PriorityQueue { - pq := NewPriorityQueue(lessFn, informerFactory, opts...) - informerFactory.Start(ctx.Done()) - informerFactory.WaitForCacheSync(ctx.Done()) - return pq -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go b/vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go deleted file mode 100644 index 09c4200ff..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/eventhandlers.go +++ /dev/null @@ -1,690 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package scheduler - -import ( - "context" - "fmt" - "strings" - "time" - - v1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/client-go/dynamic/dynamicinformer" - "k8s.io/client-go/informers" - "k8s.io/client-go/tools/cache" - corev1helpers "k8s.io/component-helpers/scheduling/corev1" - corev1nodeaffinity "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" - resourceslicetracker "k8s.io/dynamic-resource-allocation/resourceslice/tracker" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/scheduler/backend/queue" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/scheduler/profile" - "k8s.io/kubernetes/pkg/scheduler/util/assumecache" -) - -func (sched *Scheduler) addNodeToCache(obj interface{}) { - evt := framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add} - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) - logger := sched.logger - node, ok := obj.(*v1.Node) - if !ok { - logger.Error(nil, "Cannot convert to *v1.Node", "obj", obj) - return - } - - logger.V(3).Info("Add event for node", "node", klog.KObj(node)) - nodeInfo := sched.Cache.AddNode(logger, node) - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, nil, node, preCheckForNode(nodeInfo)) -} - -func (sched *Scheduler) updateNodeInCache(oldObj, newObj interface{}) { - start := time.Now() - logger := sched.logger - oldNode, ok := oldObj.(*v1.Node) - if !ok { - logger.Error(nil, "Cannot convert oldObj to *v1.Node", "oldObj", oldObj) - return - } - newNode, ok := newObj.(*v1.Node) - if !ok { - logger.Error(nil, "Cannot convert newObj to *v1.Node", "newObj", newObj) - return - } - - logger.V(4).Info("Update event for node", "node", klog.KObj(newNode)) - nodeInfo := sched.Cache.UpdateNode(logger, oldNode, newNode) - events := framework.NodeSchedulingPropertiesChange(newNode, oldNode) - - // Save the time it takes to update the node in the cache. - updatingDuration := metrics.SinceInSeconds(start) - - // Only requeue unschedulable pods if the node became more schedulable. - for _, evt := range events { - startMoving := time.Now() - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, oldNode, newNode, preCheckForNode(nodeInfo)) - movingDuration := metrics.SinceInSeconds(startMoving) - - metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(updatingDuration + movingDuration) - } -} - -func (sched *Scheduler) deleteNodeFromCache(obj interface{}) { - evt := framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Delete} - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) - - logger := sched.logger - var node *v1.Node - switch t := obj.(type) { - case *v1.Node: - node = t - case cache.DeletedFinalStateUnknown: - var ok bool - node, ok = t.Obj.(*v1.Node) - if !ok { - logger.Error(nil, "Cannot convert to *v1.Node", "obj", t.Obj) - return - } - default: - logger.Error(nil, "Cannot convert to *v1.Node", "obj", t) - return - } - - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, node, nil, nil) - - logger.V(3).Info("Delete event for node", "node", klog.KObj(node)) - if err := sched.Cache.RemoveNode(logger, node); err != nil { - logger.Error(err, "Scheduler cache RemoveNode failed") - } -} - -func (sched *Scheduler) addPodToSchedulingQueue(obj interface{}) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventUnscheduledPodAdd.Label()).Observe(metrics.SinceInSeconds(start)) - - logger := sched.logger - pod := obj.(*v1.Pod) - logger.V(3).Info("Add event for unscheduled pod", "pod", klog.KObj(pod)) - sched.SchedulingQueue.Add(logger, pod) -} - -func (sched *Scheduler) updatePodInSchedulingQueue(oldObj, newObj interface{}) { - start := time.Now() - logger := sched.logger - oldPod, newPod := oldObj.(*v1.Pod), newObj.(*v1.Pod) - // Bypass update event that carries identical objects; otherwise, a duplicated - // Pod may go through scheduling and cause unexpected behavior (see #96071). - if oldPod.ResourceVersion == newPod.ResourceVersion { - return - } - - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventUnscheduledPodUpdate.Label()).Observe(metrics.SinceInSeconds(start)) - for _, evt := range framework.PodSchedulingPropertiesChange(newPod, oldPod) { - if evt.Label() != framework.EventUnscheduledPodUpdate.Label() { - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) - } - } - - isAssumed, err := sched.Cache.IsAssumedPod(newPod) - if err != nil { - utilruntime.HandleError(fmt.Errorf("failed to check whether pod %s/%s is assumed: %v", newPod.Namespace, newPod.Name, err)) - } - if isAssumed { - return - } - - logger.V(4).Info("Update event for unscheduled pod", "pod", klog.KObj(newPod)) - sched.SchedulingQueue.Update(logger, oldPod, newPod) - if hasNominatedNodeNameChanged(oldPod, newPod) { - // Nominated node changed in pod, so we need to treat it as if the pod was deleted from the old nominated node, - // because the scheduler treats such a pod as if it was already assigned when scheduling lower or equal priority pods. - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventAssignedPodDelete, oldPod, nil, getLEPriorityPreCheck(corev1helpers.PodPriority(oldPod))) - } -} - -// hasNominatedNodeNameChanged returns true when nominated node name has existed but changed. -func hasNominatedNodeNameChanged(oldPod, newPod *v1.Pod) bool { - return len(oldPod.Status.NominatedNodeName) > 0 && oldPod.Status.NominatedNodeName != newPod.Status.NominatedNodeName -} - -func (sched *Scheduler) deletePodFromSchedulingQueue(obj interface{}) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventUnscheduledPodDelete.Label()).Observe(metrics.SinceInSeconds(start)) - - logger := sched.logger - var pod *v1.Pod - switch t := obj.(type) { - case *v1.Pod: - pod = obj.(*v1.Pod) - case cache.DeletedFinalStateUnknown: - var ok bool - pod, ok = t.Obj.(*v1.Pod) - if !ok { - utilruntime.HandleError(fmt.Errorf("unable to convert object %T to *v1.Pod in %T", obj, sched)) - return - } - default: - utilruntime.HandleError(fmt.Errorf("unable to handle object in %T: %T", sched, obj)) - return - } - - logger.V(3).Info("Delete event for unscheduled pod", "pod", klog.KObj(pod)) - sched.SchedulingQueue.Delete(pod) - fwk, err := sched.frameworkForPod(pod) - if err != nil { - // This shouldn't happen, because we only accept for scheduling the pods - // which specify a scheduler name that matches one of the profiles. - logger.Error(err, "Unable to get profile", "pod", klog.KObj(pod)) - return - } - // If a waiting pod is rejected, it indicates it's previously assumed and we're - // removing it from the scheduler cache. In this case, signal a AssignedPodDelete - // event to immediately retry some unscheduled Pods. - // Similarly when a pod that had nominated node is deleted, it can unblock scheduling of other pods, - // because the lower or equal priority pods treat such a pod as if it was assigned. - if fwk.RejectWaitingPod(pod.UID) { - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventAssignedPodDelete, pod, nil, nil) - } else if pod.Status.NominatedNodeName != "" { - // Note that a nominated pod can fall into `RejectWaitingPod` case as well, - // but in that case the `MoveAllToActiveOrBackoffQueue` already covered lower priority pods. - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventAssignedPodDelete, pod, nil, getLEPriorityPreCheck(corev1helpers.PodPriority(pod))) - } -} - -// getLEPriorityPreCheck is a PreEnqueueCheck function that selects only lower or equal priority pods. -func getLEPriorityPreCheck(priority int32) queue.PreEnqueueCheck { - return func(pod *v1.Pod) bool { - return corev1helpers.PodPriority(pod) <= priority - } -} - -func (sched *Scheduler) addPodToCache(obj interface{}) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventAssignedPodAdd.Label()).Observe(metrics.SinceInSeconds(start)) - - logger := sched.logger - pod, ok := obj.(*v1.Pod) - if !ok { - logger.Error(nil, "Cannot convert to *v1.Pod", "obj", obj) - return - } - - logger.V(3).Info("Add event for scheduled pod", "pod", klog.KObj(pod)) - if err := sched.Cache.AddPod(logger, pod); err != nil { - logger.Error(err, "Scheduler cache AddPod failed", "pod", klog.KObj(pod)) - } - - // SchedulingQueue.AssignedPodAdded has a problem: - // It internally pre-filters Pods to move to activeQ, - // while taking only in-tree plugins into consideration. - // Consequently, if custom plugins that subscribes Pod/Add events reject Pods, - // those Pods will never be requeued to activeQ by an assigned Pod related events, - // and they may be stuck in unschedulableQ. - // - // Here we use MoveAllToActiveOrBackoffQueue only when QueueingHint is enabled. - // (We cannot switch to MoveAllToActiveOrBackoffQueue right away because of throughput concern.) - if utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventAssignedPodAdd, nil, pod, nil) - } else { - sched.SchedulingQueue.AssignedPodAdded(logger, pod) - } -} - -func (sched *Scheduler) updatePodInCache(oldObj, newObj interface{}) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventAssignedPodUpdate.Label()).Observe(metrics.SinceInSeconds(start)) - - logger := sched.logger - oldPod, ok := oldObj.(*v1.Pod) - if !ok { - logger.Error(nil, "Cannot convert oldObj to *v1.Pod", "oldObj", oldObj) - return - } - newPod, ok := newObj.(*v1.Pod) - if !ok { - logger.Error(nil, "Cannot convert newObj to *v1.Pod", "newObj", newObj) - return - } - - logger.V(4).Info("Update event for scheduled pod", "pod", klog.KObj(oldPod)) - if err := sched.Cache.UpdatePod(logger, oldPod, newPod); err != nil { - logger.Error(err, "Scheduler cache UpdatePod failed", "pod", klog.KObj(oldPod)) - } - - events := framework.PodSchedulingPropertiesChange(newPod, oldPod) - - // Save the time it takes to update the pod in the cache. - updatingDuration := metrics.SinceInSeconds(start) - - for _, evt := range events { - startMoving := time.Now() - // SchedulingQueue.AssignedPodUpdated has a problem: - // It internally pre-filters Pods to move to activeQ, - // while taking only in-tree plugins into consideration. - // Consequently, if custom plugins that subscribes Pod/Update events reject Pods, - // those Pods will never be requeued to activeQ by an assigned Pod related events, - // and they may be stuck in unschedulableQ. - // - // Here we use MoveAllToActiveOrBackoffQueue only when QueueingHint is enabled. - // (We cannot switch to MoveAllToActiveOrBackoffQueue right away because of throughput concern.) - if utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, oldPod, newPod, nil) - } else { - sched.SchedulingQueue.AssignedPodUpdated(logger, oldPod, newPod, evt) - } - movingDuration := metrics.SinceInSeconds(startMoving) - metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(updatingDuration + movingDuration) - } -} - -func (sched *Scheduler) deletePodFromCache(obj interface{}) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(framework.EventAssignedPodDelete.Label()).Observe(metrics.SinceInSeconds(start)) - - logger := sched.logger - var pod *v1.Pod - switch t := obj.(type) { - case *v1.Pod: - pod = t - case cache.DeletedFinalStateUnknown: - var ok bool - pod, ok = t.Obj.(*v1.Pod) - if !ok { - logger.Error(nil, "Cannot convert to *v1.Pod", "obj", t.Obj) - return - } - default: - logger.Error(nil, "Cannot convert to *v1.Pod", "obj", t) - return - } - - logger.V(3).Info("Delete event for scheduled pod", "pod", klog.KObj(pod)) - if err := sched.Cache.RemovePod(logger, pod); err != nil { - logger.Error(err, "Scheduler cache RemovePod failed", "pod", klog.KObj(pod)) - } - - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventAssignedPodDelete, pod, nil, nil) -} - -// assignedPod selects pods that are assigned (scheduled and running). -func assignedPod(pod *v1.Pod) bool { - return len(pod.Spec.NodeName) != 0 -} - -// responsibleForPod returns true if the pod has asked to be scheduled by the given scheduler. -func responsibleForPod(pod *v1.Pod, profiles profile.Map) bool { - return profiles.HandlesSchedulerName(pod.Spec.SchedulerName) -} - -const ( - // syncedPollPeriod controls how often you look at the status of your sync funcs - syncedPollPeriod = 100 * time.Millisecond -) - -// WaitForHandlersSync waits for EventHandlers to sync. -// It returns true if it was successful, false if the controller should shut down -func (sched *Scheduler) WaitForHandlersSync(ctx context.Context) error { - return wait.PollUntilContextCancel(ctx, syncedPollPeriod, true, func(ctx context.Context) (done bool, err error) { - for _, handler := range sched.registeredHandlers { - if !handler.HasSynced() { - return false, nil - } - } - return true, nil - }) -} - -// addAllEventHandlers is a helper function used in tests and in Scheduler -// to add event handlers for various informers. -func addAllEventHandlers( - sched *Scheduler, - informerFactory informers.SharedInformerFactory, - dynInformerFactory dynamicinformer.DynamicSharedInformerFactory, - resourceClaimCache *assumecache.AssumeCache, - resourceSliceTracker *resourceslicetracker.Tracker, - gvkMap map[framework.EventResource]framework.ActionType, -) error { - var ( - handlerRegistration cache.ResourceEventHandlerRegistration - err error - handlers []cache.ResourceEventHandlerRegistration - ) - // scheduled pod cache - if handlerRegistration, err = informerFactory.Core().V1().Pods().Informer().AddEventHandler( - cache.FilteringResourceEventHandler{ - FilterFunc: func(obj interface{}) bool { - switch t := obj.(type) { - case *v1.Pod: - return assignedPod(t) - case cache.DeletedFinalStateUnknown: - if _, ok := t.Obj.(*v1.Pod); ok { - // The carried object may be stale, so we don't use it to check if - // it's assigned or not. Attempting to cleanup anyways. - return true - } - utilruntime.HandleError(fmt.Errorf("unable to convert object %T to *v1.Pod in %T", obj, sched)) - return false - default: - utilruntime.HandleError(fmt.Errorf("unable to handle object in %T: %T", sched, obj)) - return false - } - }, - Handler: cache.ResourceEventHandlerFuncs{ - AddFunc: sched.addPodToCache, - UpdateFunc: sched.updatePodInCache, - DeleteFunc: sched.deletePodFromCache, - }, - }, - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - - // unscheduled pod queue - if handlerRegistration, err = informerFactory.Core().V1().Pods().Informer().AddEventHandler( - cache.FilteringResourceEventHandler{ - FilterFunc: func(obj interface{}) bool { - switch t := obj.(type) { - case *v1.Pod: - return !assignedPod(t) && responsibleForPod(t, sched.Profiles) - case cache.DeletedFinalStateUnknown: - if pod, ok := t.Obj.(*v1.Pod); ok { - // The carried object may be stale, so we don't use it to check if - // it's assigned or not. - return responsibleForPod(pod, sched.Profiles) - } - utilruntime.HandleError(fmt.Errorf("unable to convert object %T to *v1.Pod in %T", obj, sched)) - return false - default: - utilruntime.HandleError(fmt.Errorf("unable to handle object in %T: %T", sched, obj)) - return false - } - }, - Handler: cache.ResourceEventHandlerFuncs{ - AddFunc: sched.addPodToSchedulingQueue, - UpdateFunc: sched.updatePodInSchedulingQueue, - DeleteFunc: sched.deletePodFromSchedulingQueue, - }, - }, - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - - if handlerRegistration, err = informerFactory.Core().V1().Nodes().Informer().AddEventHandler( - cache.ResourceEventHandlerFuncs{ - AddFunc: sched.addNodeToCache, - UpdateFunc: sched.updateNodeInCache, - DeleteFunc: sched.deleteNodeFromCache, - }, - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - - logger := sched.logger - buildEvtResHandler := func(at framework.ActionType, resource framework.EventResource) cache.ResourceEventHandlerFuncs { - funcs := cache.ResourceEventHandlerFuncs{} - if at&framework.Add != 0 { - evt := framework.ClusterEvent{Resource: resource, ActionType: framework.Add} - funcs.AddFunc = func(obj interface{}) { - start := time.Now() - defer metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) - if resource == framework.StorageClass && !utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { - sc, ok := obj.(*storagev1.StorageClass) - if !ok { - logger.Error(nil, "Cannot convert to *storagev1.StorageClass", "obj", obj) - return - } - - // CheckVolumeBindingPred fails if pod has unbound immediate PVCs. If these - // PVCs have specified StorageClass name, creating StorageClass objects - // with late binding will cause predicates to pass, so we need to move pods - // to active queue. - // We don't need to invalidate cached results because results will not be - // cached for pod that has unbound immediate PVCs. - if sc.VolumeBindingMode == nil || *sc.VolumeBindingMode != storagev1.VolumeBindingWaitForFirstConsumer { - return - } - } - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, nil, obj, nil) - } - } - if at&framework.Update != 0 { - evt := framework.ClusterEvent{Resource: resource, ActionType: framework.Update} - funcs.UpdateFunc = func(old, obj interface{}) { - start := time.Now() - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, old, obj, nil) - metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) - } - } - if at&framework.Delete != 0 { - evt := framework.ClusterEvent{Resource: resource, ActionType: framework.Delete} - funcs.DeleteFunc = func(obj interface{}) { - start := time.Now() - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, evt, obj, nil, nil) - metrics.EventHandlingLatency.WithLabelValues(evt.Label()).Observe(metrics.SinceInSeconds(start)) - } - } - return funcs - } - - for gvk, at := range gvkMap { - switch gvk { - case framework.Node, framework.Pod: - // Do nothing. - case framework.CSINode: - if handlerRegistration, err = informerFactory.Storage().V1().CSINodes().Informer().AddEventHandler( - buildEvtResHandler(at, framework.CSINode), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - case framework.CSIDriver: - if handlerRegistration, err = informerFactory.Storage().V1().CSIDrivers().Informer().AddEventHandler( - buildEvtResHandler(at, framework.CSIDriver), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - case framework.CSIStorageCapacity: - if handlerRegistration, err = informerFactory.Storage().V1().CSIStorageCapacities().Informer().AddEventHandler( - buildEvtResHandler(at, framework.CSIStorageCapacity), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - case framework.PersistentVolume: - // MaxPDVolumeCountPredicate: since it relies on the counts of PV. - // - // PvAdd: Pods created when there are no PVs available will be stuck in - // unschedulable queue. But unbound PVs created for static provisioning and - // delay binding storage class are skipped in PV controller dynamic - // provisioning and binding process, will not trigger events to schedule pod - // again. So we need to move pods to active queue on PV add for this - // scenario. - // - // PvUpdate: Scheduler.bindVolumesWorker may fail to update assumed pod volume - // bindings due to conflicts if PVs are updated by PV controller or other - // parties, then scheduler will add pod back to unschedulable queue. We - // need to move pods to active queue on PV update for this scenario. - if handlerRegistration, err = informerFactory.Core().V1().PersistentVolumes().Informer().AddEventHandler( - buildEvtResHandler(at, framework.PersistentVolume), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - case framework.PersistentVolumeClaim: - // MaxPDVolumeCountPredicate: add/update PVC will affect counts of PV when it is bound. - if handlerRegistration, err = informerFactory.Core().V1().PersistentVolumeClaims().Informer().AddEventHandler( - buildEvtResHandler(at, framework.PersistentVolumeClaim), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - case framework.ResourceClaim: - if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - handlerRegistration = resourceClaimCache.AddEventHandler( - buildEvtResHandler(at, framework.ResourceClaim), - ) - handlers = append(handlers, handlerRegistration) - } - case framework.ResourceSlice: - if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - if handlerRegistration, err = resourceSliceTracker.AddEventHandler( - buildEvtResHandler(at, framework.ResourceSlice), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - } - case framework.DeviceClass: - if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - if handlerRegistration, err = informerFactory.Resource().V1beta1().DeviceClasses().Informer().AddEventHandler( - buildEvtResHandler(at, framework.DeviceClass), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - } - case framework.StorageClass: - if handlerRegistration, err = informerFactory.Storage().V1().StorageClasses().Informer().AddEventHandler( - buildEvtResHandler(at, framework.StorageClass), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - case framework.VolumeAttachment: - if handlerRegistration, err = informerFactory.Storage().V1().VolumeAttachments().Informer().AddEventHandler( - buildEvtResHandler(at, framework.VolumeAttachment), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - default: - // Tests may not instantiate dynInformerFactory. - if dynInformerFactory == nil { - continue - } - // GVK is expected to be at least 3-folded, separated by dots. - // .. - // Valid examples: - // - foos.v1.example.com - // - bars.v1beta1.a.b.c - // Invalid examples: - // - foos.v1 (2 sections) - // - foo.v1.example.com (the first section should be plural) - if strings.Count(string(gvk), ".") < 2 { - logger.Error(nil, "incorrect event registration", "gvk", gvk) - continue - } - // Fall back to try dynamic informers. - gvr, _ := schema.ParseResourceArg(string(gvk)) - dynInformer := dynInformerFactory.ForResource(*gvr).Informer() - if handlerRegistration, err = dynInformer.AddEventHandler( - buildEvtResHandler(at, gvk), - ); err != nil { - return err - } - handlers = append(handlers, handlerRegistration) - } - } - sched.registeredHandlers = handlers - return nil -} - -func preCheckForNode(nodeInfo *framework.NodeInfo) queue.PreEnqueueCheck { - if utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { - // QHint is initially created from the motivation of replacing this preCheck. - // It assumes that the scheduler only has in-tree plugins, which is problematic for our extensibility. - // Here, we skip preCheck if QHint is enabled, and we eventually remove it after QHint is graduated. - return nil - } - - // Note: the following checks doesn't take preemption into considerations, in very rare - // cases (e.g., node resizing), "pod" may still fail a check but preemption helps. We deliberately - // chose to ignore those cases as unschedulable pods will be re-queued eventually. - return func(pod *v1.Pod) bool { - admissionResults := AdmissionCheck(pod, nodeInfo, false) - if len(admissionResults) != 0 { - return false - } - _, isUntolerated := corev1helpers.FindMatchingUntoleratedTaint(nodeInfo.Node().Spec.Taints, pod.Spec.Tolerations, func(t *v1.Taint) bool { - return t.Effect == v1.TaintEffectNoSchedule - }) - return !isUntolerated - } -} - -// AdmissionCheck calls the filtering logic of noderesources/nodeport/nodeAffinity/nodename -// and returns the failure reasons. It's used in kubelet(pkg/kubelet/lifecycle/predicate.go) and scheduler. -// It returns the first failure if `includeAllFailures` is set to false; otherwise -// returns all failures. -func AdmissionCheck(pod *v1.Pod, nodeInfo *framework.NodeInfo, includeAllFailures bool) []AdmissionResult { - var admissionResults []AdmissionResult - insufficientResources := noderesources.Fits(pod, nodeInfo, noderesources.ResourceRequestsOptions{ - EnablePodLevelResources: utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources), - }) - if len(insufficientResources) != 0 { - for i := range insufficientResources { - admissionResults = append(admissionResults, AdmissionResult{InsufficientResource: &insufficientResources[i]}) - } - if !includeAllFailures { - return admissionResults - } - } - - if matches, _ := corev1nodeaffinity.GetRequiredNodeAffinity(pod).Match(nodeInfo.Node()); !matches { - admissionResults = append(admissionResults, AdmissionResult{Name: nodeaffinity.Name, Reason: nodeaffinity.ErrReasonPod}) - if !includeAllFailures { - return admissionResults - } - } - if !nodename.Fits(pod, nodeInfo) { - admissionResults = append(admissionResults, AdmissionResult{Name: nodename.Name, Reason: nodename.ErrReason}) - if !includeAllFailures { - return admissionResults - } - } - if !nodeports.Fits(pod, nodeInfo) { - admissionResults = append(admissionResults, AdmissionResult{Name: nodeports.Name, Reason: nodeports.ErrReason}) - if !includeAllFailures { - return admissionResults - } - } - return admissionResults -} - -// AdmissionResult describes the reason why Scheduler can't admit the pod. -// If the reason is a resource fit one, then AdmissionResult.InsufficientResource includes the details. -type AdmissionResult struct { - Name string - Reason string - InsufficientResource *noderesources.InsufficientResource -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/extender.go b/vendor/k8s.io/kubernetes/pkg/scheduler/extender.go deleted file mode 100644 index 2a4866c4d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/extender.go +++ /dev/null @@ -1,456 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package scheduler - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "net/http" - "strings" - "time" - - v1 "k8s.io/api/core/v1" - utilnet "k8s.io/apimachinery/pkg/util/net" - "k8s.io/apimachinery/pkg/util/sets" - restclient "k8s.io/client-go/rest" - extenderv1 "k8s.io/kube-scheduler/extender/v1" - schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -const ( - // DefaultExtenderTimeout defines the default extender timeout in second. - DefaultExtenderTimeout = 5 * time.Second -) - -// HTTPExtender implements the Extender interface. -type HTTPExtender struct { - extenderURL string - preemptVerb string - filterVerb string - prioritizeVerb string - bindVerb string - weight int64 - client *http.Client - nodeCacheCapable bool - managedResources sets.Set[string] - ignorable bool -} - -func makeTransport(config *schedulerapi.Extender) (http.RoundTripper, error) { - var cfg restclient.Config - if config.TLSConfig != nil { - cfg.TLSClientConfig.Insecure = config.TLSConfig.Insecure - cfg.TLSClientConfig.ServerName = config.TLSConfig.ServerName - cfg.TLSClientConfig.CertFile = config.TLSConfig.CertFile - cfg.TLSClientConfig.KeyFile = config.TLSConfig.KeyFile - cfg.TLSClientConfig.CAFile = config.TLSConfig.CAFile - cfg.TLSClientConfig.CertData = config.TLSConfig.CertData - cfg.TLSClientConfig.KeyData = config.TLSConfig.KeyData - cfg.TLSClientConfig.CAData = config.TLSConfig.CAData - } - if config.EnableHTTPS { - hasCA := len(cfg.CAFile) > 0 || len(cfg.CAData) > 0 - if !hasCA { - cfg.Insecure = true - } - } - tlsConfig, err := restclient.TLSConfigFor(&cfg) - if err != nil { - return nil, err - } - if tlsConfig != nil { - return utilnet.SetTransportDefaults(&http.Transport{ - TLSClientConfig: tlsConfig, - }), nil - } - return utilnet.SetTransportDefaults(&http.Transport{}), nil -} - -// NewHTTPExtender creates an HTTPExtender object. -func NewHTTPExtender(config *schedulerapi.Extender) (framework.Extender, error) { - if config.HTTPTimeout.Duration.Nanoseconds() == 0 { - config.HTTPTimeout.Duration = time.Duration(DefaultExtenderTimeout) - } - - transport, err := makeTransport(config) - if err != nil { - return nil, err - } - client := &http.Client{ - Transport: transport, - Timeout: config.HTTPTimeout.Duration, - } - managedResources := sets.New[string]() - for _, r := range config.ManagedResources { - managedResources.Insert(string(r.Name)) - } - return &HTTPExtender{ - extenderURL: config.URLPrefix, - preemptVerb: config.PreemptVerb, - filterVerb: config.FilterVerb, - prioritizeVerb: config.PrioritizeVerb, - bindVerb: config.BindVerb, - weight: config.Weight, - client: client, - nodeCacheCapable: config.NodeCacheCapable, - managedResources: managedResources, - ignorable: config.Ignorable, - }, nil -} - -// Name returns extenderURL to identify the extender. -func (h *HTTPExtender) Name() string { - return h.extenderURL -} - -// IsIgnorable returns true indicates scheduling should not fail when this extender -// is unavailable -func (h *HTTPExtender) IsIgnorable() bool { - return h.ignorable -} - -// SupportsPreemption returns true if an extender supports preemption. -// An extender should have preempt verb defined and enabled its own node cache. -func (h *HTTPExtender) SupportsPreemption() bool { - return len(h.preemptVerb) > 0 -} - -// ProcessPreemption returns filtered candidate nodes and victims after running preemption logic in extender. -func (h *HTTPExtender) ProcessPreemption( - pod *v1.Pod, - nodeNameToVictims map[string]*extenderv1.Victims, - nodeInfos framework.NodeInfoLister, -) (map[string]*extenderv1.Victims, error) { - var ( - result extenderv1.ExtenderPreemptionResult - args *extenderv1.ExtenderPreemptionArgs - ) - - if !h.SupportsPreemption() { - return nil, fmt.Errorf("preempt verb is not defined for extender %v but run into ProcessPreemption", h.extenderURL) - } - - if h.nodeCacheCapable { - // If extender has cached node info, pass NodeNameToMetaVictims in args. - nodeNameToMetaVictims := convertToMetaVictims(nodeNameToVictims) - args = &extenderv1.ExtenderPreemptionArgs{ - Pod: pod, - NodeNameToMetaVictims: nodeNameToMetaVictims, - } - } else { - args = &extenderv1.ExtenderPreemptionArgs{ - Pod: pod, - NodeNameToVictims: nodeNameToVictims, - } - } - - if err := h.send(h.preemptVerb, args, &result); err != nil { - return nil, err - } - - // Extender will always return NodeNameToMetaVictims. - // So let's convert it to NodeNameToVictims by using . - newNodeNameToVictims, err := h.convertToVictims(result.NodeNameToMetaVictims, nodeInfos) - if err != nil { - return nil, err - } - // Do not override . - return newNodeNameToVictims, nil -} - -// convertToVictims converts "nodeNameToMetaVictims" from object identifiers, -// such as UIDs and names, to object pointers. -func (h *HTTPExtender) convertToVictims( - nodeNameToMetaVictims map[string]*extenderv1.MetaVictims, - nodeInfos framework.NodeInfoLister, -) (map[string]*extenderv1.Victims, error) { - nodeNameToVictims := map[string]*extenderv1.Victims{} - for nodeName, metaVictims := range nodeNameToMetaVictims { - nodeInfo, err := nodeInfos.Get(nodeName) - if err != nil { - return nil, err - } - victims := &extenderv1.Victims{ - Pods: []*v1.Pod{}, - NumPDBViolations: metaVictims.NumPDBViolations, - } - for _, metaPod := range metaVictims.Pods { - pod, err := h.convertPodUIDToPod(metaPod, nodeInfo) - if err != nil { - return nil, err - } - victims.Pods = append(victims.Pods, pod) - } - nodeNameToVictims[nodeName] = victims - } - return nodeNameToVictims, nil -} - -// convertPodUIDToPod returns v1.Pod object for given MetaPod and node info. -// The v1.Pod object is restored by nodeInfo.Pods(). -// It returns an error if there's cache inconsistency between default scheduler -// and extender, i.e. when the pod is not found in nodeInfo.Pods. -func (h *HTTPExtender) convertPodUIDToPod( - metaPod *extenderv1.MetaPod, - nodeInfo *framework.NodeInfo) (*v1.Pod, error) { - for _, p := range nodeInfo.Pods { - if string(p.Pod.UID) == metaPod.UID { - return p.Pod, nil - } - } - return nil, fmt.Errorf("extender: %v claims to preempt pod (UID: %v) on node: %v, but the pod is not found on that node", - h.extenderURL, metaPod, nodeInfo.Node().Name) -} - -// convertToMetaVictims converts from struct type to meta types. -func convertToMetaVictims( - nodeNameToVictims map[string]*extenderv1.Victims, -) map[string]*extenderv1.MetaVictims { - nodeNameToMetaVictims := map[string]*extenderv1.MetaVictims{} - for node, victims := range nodeNameToVictims { - metaVictims := &extenderv1.MetaVictims{ - Pods: []*extenderv1.MetaPod{}, - NumPDBViolations: victims.NumPDBViolations, - } - for _, pod := range victims.Pods { - metaPod := &extenderv1.MetaPod{ - UID: string(pod.UID), - } - metaVictims.Pods = append(metaVictims.Pods, metaPod) - } - nodeNameToMetaVictims[node] = metaVictims - } - return nodeNameToMetaVictims -} - -// Filter based on extender implemented predicate functions. The filtered list is -// expected to be a subset of the supplied list; otherwise the function returns an error. -// The failedNodes and failedAndUnresolvableNodes optionally contains the list -// of failed nodes and failure reasons, except nodes in the latter are -// unresolvable. -func (h *HTTPExtender) Filter( - pod *v1.Pod, - nodes []*framework.NodeInfo, -) (filteredList []*framework.NodeInfo, failedNodes, failedAndUnresolvableNodes extenderv1.FailedNodesMap, err error) { - var ( - result extenderv1.ExtenderFilterResult - nodeList *v1.NodeList - nodeNames *[]string - nodeResult []*framework.NodeInfo - args *extenderv1.ExtenderArgs - ) - fromNodeName := make(map[string]*framework.NodeInfo) - for _, n := range nodes { - fromNodeName[n.Node().Name] = n - } - - if h.filterVerb == "" { - return nodes, extenderv1.FailedNodesMap{}, extenderv1.FailedNodesMap{}, nil - } - - if h.nodeCacheCapable { - nodeNameSlice := make([]string, 0, len(nodes)) - for _, node := range nodes { - nodeNameSlice = append(nodeNameSlice, node.Node().Name) - } - nodeNames = &nodeNameSlice - } else { - nodeList = &v1.NodeList{} - for _, node := range nodes { - nodeList.Items = append(nodeList.Items, *node.Node()) - } - } - - args = &extenderv1.ExtenderArgs{ - Pod: pod, - Nodes: nodeList, - NodeNames: nodeNames, - } - - if err := h.send(h.filterVerb, args, &result); err != nil { - return nil, nil, nil, err - } - if result.Error != "" { - return nil, nil, nil, errors.New(result.Error) - } - - if h.nodeCacheCapable && result.NodeNames != nil { - nodeResult = make([]*framework.NodeInfo, len(*result.NodeNames)) - for i, nodeName := range *result.NodeNames { - if n, ok := fromNodeName[nodeName]; ok { - nodeResult[i] = n - } else { - return nil, nil, nil, fmt.Errorf( - "extender %q claims a filtered node %q which is not found in the input node list", - h.extenderURL, nodeName) - } - } - } else if result.Nodes != nil { - nodeResult = make([]*framework.NodeInfo, len(result.Nodes.Items)) - for i := range result.Nodes.Items { - nodeResult[i] = framework.NewNodeInfo() - nodeResult[i].SetNode(&result.Nodes.Items[i]) - } - } - - return nodeResult, result.FailedNodes, result.FailedAndUnresolvableNodes, nil -} - -// Prioritize based on extender implemented priority functions. Weight*priority is added -// up for each such priority function. The returned score is added to the score computed -// by Kubernetes scheduler. The total score is used to do the host selection. -func (h *HTTPExtender) Prioritize(pod *v1.Pod, nodes []*framework.NodeInfo) (*extenderv1.HostPriorityList, int64, error) { - var ( - result extenderv1.HostPriorityList - nodeList *v1.NodeList - nodeNames *[]string - args *extenderv1.ExtenderArgs - ) - - if h.prioritizeVerb == "" { - result := extenderv1.HostPriorityList{} - for _, node := range nodes { - result = append(result, extenderv1.HostPriority{Host: node.Node().Name, Score: 0}) - } - return &result, 0, nil - } - - if h.nodeCacheCapable { - nodeNameSlice := make([]string, 0, len(nodes)) - for _, node := range nodes { - nodeNameSlice = append(nodeNameSlice, node.Node().Name) - } - nodeNames = &nodeNameSlice - } else { - nodeList = &v1.NodeList{} - for _, node := range nodes { - nodeList.Items = append(nodeList.Items, *node.Node()) - } - } - - args = &extenderv1.ExtenderArgs{ - Pod: pod, - Nodes: nodeList, - NodeNames: nodeNames, - } - - if err := h.send(h.prioritizeVerb, args, &result); err != nil { - return nil, 0, err - } - return &result, h.weight, nil -} - -// Bind delegates the action of binding a pod to a node to the extender. -func (h *HTTPExtender) Bind(binding *v1.Binding) error { - var result extenderv1.ExtenderBindingResult - if !h.IsBinder() { - // This shouldn't happen as this extender wouldn't have become a Binder. - return fmt.Errorf("unexpected empty bindVerb in extender") - } - req := &extenderv1.ExtenderBindingArgs{ - PodName: binding.Name, - PodNamespace: binding.Namespace, - PodUID: binding.UID, - Node: binding.Target.Name, - } - if err := h.send(h.bindVerb, req, &result); err != nil { - return err - } - if result.Error != "" { - return errors.New(result.Error) - } - return nil -} - -// IsBinder returns whether this extender is configured for the Bind method. -func (h *HTTPExtender) IsBinder() bool { - return h.bindVerb != "" -} - -// IsPrioritizer returns whether this extender is configured for the Prioritize method. -func (h *HTTPExtender) IsPrioritizer() bool { - return h.prioritizeVerb != "" -} - -// IsFilter returns whether this extender is configured for the Filter method. -func (h *HTTPExtender) IsFilter() bool { - return h.filterVerb != "" -} - -// Helper function to send messages to the extender -func (h *HTTPExtender) send(action string, args interface{}, result interface{}) error { - out, err := json.Marshal(args) - if err != nil { - return err - } - - url := strings.TrimRight(h.extenderURL, "/") + "/" + action - - req, err := http.NewRequest("POST", url, bytes.NewReader(out)) - if err != nil { - return err - } - - req.Header.Set("Content-Type", "application/json") - - resp, err := h.client.Do(req) - if err != nil { - return err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - return fmt.Errorf("failed %v with extender at URL %v, code %v", action, url, resp.StatusCode) - } - - return json.NewDecoder(resp.Body).Decode(result) -} - -// IsInterested returns true if at least one extended resource requested by -// this pod is managed by this extender. -func (h *HTTPExtender) IsInterested(pod *v1.Pod) bool { - if h.managedResources.Len() == 0 { - return true - } - if h.hasManagedResources(pod.Spec.Containers) { - return true - } - if h.hasManagedResources(pod.Spec.InitContainers) { - return true - } - return false -} - -func (h *HTTPExtender) hasManagedResources(containers []v1.Container) bool { - for i := range containers { - container := &containers[i] - for resourceName := range container.Resources.Requests { - if h.managedResources.Has(string(resourceName)) { - return true - } - } - for resourceName := range container.Resources.Limits { - if h.managedResources.Has(string(resourceName)) { - return true - } - } - } - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go deleted file mode 100644 index 710e16daf..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/cycle_state.go +++ /dev/null @@ -1,123 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package framework - -import ( - "errors" - "sync" - - "k8s.io/apimachinery/pkg/util/sets" -) - -var ( - // ErrNotFound is the not found error message. - ErrNotFound = errors.New("not found") -) - -// StateData is a generic type for arbitrary data stored in CycleState. -type StateData interface { - // Clone is an interface to make a copy of StateData. For performance reasons, - // clone should make shallow copies for members (e.g., slices or maps) that are not - // impacted by PreFilter's optional AddPod/RemovePod methods. - Clone() StateData -} - -// StateKey is the type of keys stored in CycleState. -type StateKey string - -// CycleState provides a mechanism for plugins to store and retrieve arbitrary data. -// StateData stored by one plugin can be read, altered, or deleted by another plugin. -// CycleState does not provide any data protection, as all plugins are assumed to be -// trusted. -// Note: CycleState uses a sync.Map to back the storage, because it is thread safe. It's aimed to optimize for the "write once and read many times" scenarios. -// It is the recommended pattern used in all in-tree plugins - plugin-specific state is written once in PreFilter/PreScore and afterward read many times in Filter/Score. -type CycleState struct { - // storage is keyed with StateKey, and valued with StateData. - storage sync.Map - // if recordPluginMetrics is true, metrics.PluginExecutionDuration will be recorded for this cycle. - recordPluginMetrics bool - // SkipFilterPlugins are plugins that will be skipped in the Filter extension point. - SkipFilterPlugins sets.Set[string] - // SkipScorePlugins are plugins that will be skipped in the Score extension point. - SkipScorePlugins sets.Set[string] -} - -// NewCycleState initializes a new CycleState and returns its pointer. -func NewCycleState() *CycleState { - return &CycleState{} -} - -// ShouldRecordPluginMetrics returns whether metrics.PluginExecutionDuration metrics should be recorded. -func (c *CycleState) ShouldRecordPluginMetrics() bool { - if c == nil { - return false - } - return c.recordPluginMetrics -} - -// SetRecordPluginMetrics sets recordPluginMetrics to the given value. -func (c *CycleState) SetRecordPluginMetrics(flag bool) { - if c == nil { - return - } - c.recordPluginMetrics = flag -} - -// Clone creates a copy of CycleState and returns its pointer. Clone returns -// nil if the context being cloned is nil. -func (c *CycleState) Clone() *CycleState { - if c == nil { - return nil - } - copy := NewCycleState() - // Safe copy storage in case of overwriting. - c.storage.Range(func(k, v interface{}) bool { - copy.storage.Store(k, v.(StateData).Clone()) - return true - }) - // The below are not mutated, so we don't have to safe copy. - copy.recordPluginMetrics = c.recordPluginMetrics - copy.SkipFilterPlugins = c.SkipFilterPlugins - copy.SkipScorePlugins = c.SkipScorePlugins - - return copy -} - -// Read retrieves data with the given "key" from CycleState. If the key is not -// present, ErrNotFound is returned. -// -// See CycleState for notes on concurrency. -func (c *CycleState) Read(key StateKey) (StateData, error) { - if v, ok := c.storage.Load(key); ok { - return v.(StateData), nil - } - return nil, ErrNotFound -} - -// Write stores the given "val" in CycleState with the given "key". -// -// See CycleState for notes on concurrency. -func (c *CycleState) Write(key StateKey, val StateData) { - c.storage.Store(key, val) -} - -// Delete deletes data with the given key from CycleState. -// -// See CycleState for notes on concurrency. -func (c *CycleState) Delete(key StateKey) { - c.storage.Delete(key) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/events.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/events.go deleted file mode 100644 index 1fe1b0b97..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/events.go +++ /dev/null @@ -1,231 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package framework - -import ( - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/equality" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/component-helpers/resource" - "k8s.io/dynamic-resource-allocation/resourceclaim" - "k8s.io/kubernetes/pkg/features" -) - -// Special event labels. -const ( - // ScheduleAttemptFailure is the event when a schedule attempt fails. - ScheduleAttemptFailure = "ScheduleAttemptFailure" - // BackoffComplete is the event when a pod finishes backoff. - BackoffComplete = "BackoffComplete" - // PopFromBackoffQ is the event when a pod is popped from backoffQ when activeQ is empty. - PopFromBackoffQ = "PopFromBackoffQ" - // ForceActivate is the event when a pod is moved from unschedulablePods/backoffQ - // to activeQ. Usually it's triggered by plugin implementations. - ForceActivate = "ForceActivate" - // UnschedulableTimeout is the event when a pod is moved from unschedulablePods - // due to the timeout specified at pod-max-in-unschedulable-pods-duration. - UnschedulableTimeout = "UnschedulableTimeout" -) - -var ( - // EventAssignedPodAdd is the event when an assigned pod is added. - EventAssignedPodAdd = ClusterEvent{Resource: assignedPod, ActionType: Add} - // EventAssignedPodUpdate is the event when an assigned pod is updated. - EventAssignedPodUpdate = ClusterEvent{Resource: assignedPod, ActionType: Update} - // EventAssignedPodDelete is the event when an assigned pod is deleted. - EventAssignedPodDelete = ClusterEvent{Resource: assignedPod, ActionType: Delete} - // EventUnscheduledPodAdd is the event when an unscheduled pod is added. - EventUnscheduledPodAdd = ClusterEvent{Resource: unschedulablePod, ActionType: Add} - // EventUnscheduledPodUpdate is the event when an unscheduled pod is updated. - EventUnscheduledPodUpdate = ClusterEvent{Resource: unschedulablePod, ActionType: Update} - // EventUnscheduledPodDelete is the event when an unscheduled pod is deleted. - EventUnscheduledPodDelete = ClusterEvent{Resource: unschedulablePod, ActionType: Delete} - // EventUnschedulableTimeout is the event when a pod stays in unschedulable for longer than timeout. - EventUnschedulableTimeout = ClusterEvent{Resource: WildCard, ActionType: All, label: UnschedulableTimeout} - // EventForceActivate is the event when a pod is moved from unschedulablePods/backoffQ to activeQ. - EventForceActivate = ClusterEvent{Resource: WildCard, ActionType: All, label: ForceActivate} -) - -// PodSchedulingPropertiesChange interprets the update of a pod and returns corresponding UpdatePodXYZ event(s). -// Once we have other pod update events, we should update here as well. -func PodSchedulingPropertiesChange(newPod *v1.Pod, oldPod *v1.Pod) (events []ClusterEvent) { - r := assignedPod - if newPod.Spec.NodeName == "" { - r = unschedulablePod - } - - podChangeExtracters := []podChangeExtractor{ - extractPodLabelsChange, - extractPodScaleDown, - extractPodSchedulingGateEliminatedChange, - extractPodTolerationChange, - } - if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - podChangeExtracters = append(podChangeExtracters, extractPodGeneratedResourceClaimChange) - } - - for _, fn := range podChangeExtracters { - if event := fn(newPod, oldPod); event != none { - events = append(events, ClusterEvent{Resource: r, ActionType: event}) - } - } - - if len(events) == 0 { - // When no specific event is found, we use AssignedPodOtherUpdate, - // which should only trigger plugins registering a general Pod/Update event. - events = append(events, ClusterEvent{Resource: r, ActionType: updatePodOther}) - } - - return -} - -type podChangeExtractor func(newPod *v1.Pod, oldPod *v1.Pod) ActionType - -// extractPodScaleDown interprets the update of a pod and returns PodRequestScaledDown event if any pod's resource request(s) is scaled down. -func extractPodScaleDown(newPod, oldPod *v1.Pod) ActionType { - opt := resource.PodResourcesOptions{ - UseStatusResources: utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling), - } - newPodRequests := resource.PodRequests(newPod, opt) - oldPodRequests := resource.PodRequests(oldPod, opt) - - for rName, oldReq := range oldPodRequests { - newReq, ok := newPodRequests[rName] - if !ok { - // The resource request of rName is removed. - return UpdatePodScaleDown - } - - if oldReq.MilliValue() > newReq.MilliValue() { - // The resource request of rName is scaled down. - return UpdatePodScaleDown - } - } - - return none -} - -func extractPodLabelsChange(newPod *v1.Pod, oldPod *v1.Pod) ActionType { - if isLabelChanged(newPod.GetLabels(), oldPod.GetLabels()) { - return UpdatePodLabel - } - return none -} - -func extractPodTolerationChange(newPod *v1.Pod, oldPod *v1.Pod) ActionType { - if len(newPod.Spec.Tolerations) != len(oldPod.Spec.Tolerations) { - // A Pod got a new toleration. - // Due to API validation, the user can add, but cannot modify or remove tolerations. - // So, it's enough to just check the length of tolerations to notice the update. - // And, any updates in tolerations could make Pod schedulable. - return UpdatePodToleration - } - - return none -} - -func extractPodSchedulingGateEliminatedChange(newPod *v1.Pod, oldPod *v1.Pod) ActionType { - if len(newPod.Spec.SchedulingGates) == 0 && len(oldPod.Spec.SchedulingGates) != 0 { - // A scheduling gate on the pod is completely removed. - return UpdatePodSchedulingGatesEliminated - } - - return none -} - -func extractPodGeneratedResourceClaimChange(newPod *v1.Pod, oldPod *v1.Pod) ActionType { - if !resourceclaim.PodStatusEqual(newPod.Status.ResourceClaimStatuses, oldPod.Status.ResourceClaimStatuses) { - return UpdatePodGeneratedResourceClaim - } - - return none -} - -// NodeSchedulingPropertiesChange interprets the update of a node and returns corresponding UpdateNodeXYZ event(s). -func NodeSchedulingPropertiesChange(newNode *v1.Node, oldNode *v1.Node) (events []ClusterEvent) { - nodeChangeExtracters := []nodeChangeExtractor{ - extractNodeSpecUnschedulableChange, - extractNodeAllocatableChange, - extractNodeLabelsChange, - extractNodeTaintsChange, - extractNodeConditionsChange, - extractNodeAnnotationsChange, - } - - for _, fn := range nodeChangeExtracters { - if event := fn(newNode, oldNode); event != none { - events = append(events, ClusterEvent{Resource: Node, ActionType: event}) - } - } - return -} - -type nodeChangeExtractor func(newNode *v1.Node, oldNode *v1.Node) ActionType - -func extractNodeAllocatableChange(newNode *v1.Node, oldNode *v1.Node) ActionType { - if !equality.Semantic.DeepEqual(oldNode.Status.Allocatable, newNode.Status.Allocatable) { - return UpdateNodeAllocatable - } - return none -} - -func extractNodeLabelsChange(newNode *v1.Node, oldNode *v1.Node) ActionType { - if isLabelChanged(newNode.GetLabels(), oldNode.GetLabels()) { - return UpdateNodeLabel - } - return none -} - -func isLabelChanged(newLabels map[string]string, oldLabels map[string]string) bool { - return !equality.Semantic.DeepEqual(newLabels, oldLabels) -} - -func extractNodeTaintsChange(newNode *v1.Node, oldNode *v1.Node) ActionType { - if !equality.Semantic.DeepEqual(newNode.Spec.Taints, oldNode.Spec.Taints) { - return UpdateNodeTaint - } - return none -} - -func extractNodeConditionsChange(newNode *v1.Node, oldNode *v1.Node) ActionType { - strip := func(conditions []v1.NodeCondition) map[v1.NodeConditionType]v1.ConditionStatus { - conditionStatuses := make(map[v1.NodeConditionType]v1.ConditionStatus, len(conditions)) - for i := range conditions { - conditionStatuses[conditions[i].Type] = conditions[i].Status - } - return conditionStatuses - } - if !equality.Semantic.DeepEqual(strip(oldNode.Status.Conditions), strip(newNode.Status.Conditions)) { - return UpdateNodeCondition - } - return none -} - -func extractNodeSpecUnschedulableChange(newNode *v1.Node, oldNode *v1.Node) ActionType { - if newNode.Spec.Unschedulable != oldNode.Spec.Unschedulable && !newNode.Spec.Unschedulable { - // TODO: create UpdateNodeSpecUnschedulable ActionType - return UpdateNodeTaint - } - return none -} - -func extractNodeAnnotationsChange(newNode *v1.Node, oldNode *v1.Node) ActionType { - if !equality.Semantic.DeepEqual(oldNode.GetAnnotations(), newNode.GetAnnotations()) { - return UpdateNodeAnnotation - } - return none -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/extender.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/extender.go deleted file mode 100644 index b0b937c36..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/extender.go +++ /dev/null @@ -1,79 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package framework - -import ( - v1 "k8s.io/api/core/v1" - extenderv1 "k8s.io/kube-scheduler/extender/v1" -) - -// Extender is an interface for external processes to influence scheduling -// decisions made by Kubernetes. This is typically needed for resources not directly -// managed by Kubernetes. -type Extender interface { - // Name returns a unique name that identifies the extender. - Name() string - - // Filter based on extender-implemented predicate functions. The filtered list is - // expected to be a subset of the supplied list. - // The failedNodes and failedAndUnresolvableNodes optionally contains the list - // of failed nodes and failure reasons, except nodes in the latter are - // unresolvable. - Filter(pod *v1.Pod, nodes []*NodeInfo) (filteredNodes []*NodeInfo, failedNodesMap extenderv1.FailedNodesMap, failedAndUnresolvable extenderv1.FailedNodesMap, err error) - - // Prioritize based on extender-implemented priority functions. The returned scores & weight - // are used to compute the weighted score for an extender. The weighted scores are added to - // the scores computed by Kubernetes scheduler. The total scores are used to do the host selection. - Prioritize(pod *v1.Pod, nodes []*NodeInfo) (hostPriorities *extenderv1.HostPriorityList, weight int64, err error) - - // Bind delegates the action of binding a pod to a node to the extender. - Bind(binding *v1.Binding) error - - // IsBinder returns whether this extender is configured for the Bind method. - IsBinder() bool - - // IsInterested returns true if at least one extended resource requested by - // this pod is managed by this extender. - IsInterested(pod *v1.Pod) bool - - // IsPrioritizer returns whether this extender is configured for the Prioritize method. - IsPrioritizer() bool - - // IsFilter returns whether this extender is configured for the Filter method. - IsFilter() bool - - // ProcessPreemption returns nodes with their victim pods processed by extender based on - // given: - // 1. Pod to schedule - // 2. Candidate nodes and victim pods (nodeNameToVictims) generated by previous scheduling process. - // The possible changes made by extender may include: - // 1. Subset of given candidate nodes after preemption phase of extender. - // 2. A different set of victim pod for every given candidate node after preemption phase of extender. - ProcessPreemption( - pod *v1.Pod, - nodeNameToVictims map[string]*extenderv1.Victims, - nodeInfos NodeInfoLister, - ) (map[string]*extenderv1.Victims, error) - - // SupportsPreemption returns if the scheduler extender support preemption or not. - SupportsPreemption() bool - - // IsIgnorable returns true indicates scheduling should not fail when this extender - // is unavailable. This gives scheduler ability to fail fast and tolerate non-critical extenders as well. - // Both Filter and Bind actions are supported. - IsIgnorable() bool -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go deleted file mode 100644 index 10ee4203d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/interface.go +++ /dev/null @@ -1,954 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// This file defines the scheduling framework plugin interfaces. - -package framework - -import ( - "context" - "errors" - "math" - "strings" - "sync" - "time" - - "github.com/google/go-cmp/cmp" //nolint:depguard - "github.com/google/go-cmp/cmp/cmpopts" //nolint:depguard - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/informers" - clientset "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/events" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" -) - -// NodeScoreList declares a list of nodes and their scores. -type NodeScoreList []NodeScore - -// NodeScore is a struct with node name and score. -type NodeScore struct { - Name string - Score int64 -} - -// NodeToStatusReader is a read-only interface of NodeToStatus passed to each PostFilter plugin. -type NodeToStatusReader interface { - // Get returns the status for given nodeName. - // If the node is not in the map, the AbsentNodesStatus is returned. - Get(nodeName string) *Status - // NodesForStatusCode returns a list of NodeInfos for the nodes that have a given status code. - // It returns the NodeInfos for all matching nodes denoted by AbsentNodesStatus as well. - NodesForStatusCode(nodeLister NodeInfoLister, code Code) ([]*NodeInfo, error) -} - -// NodeToStatusMap is an alias for NodeToStatusReader to keep partial backwards compatibility. -// NodeToStatusReader should be used if possible. -type NodeToStatusMap = NodeToStatusReader - -// NodeToStatus contains the statuses of the Nodes where the incoming Pod was not schedulable. -type NodeToStatus struct { - // nodeToStatus contains specific statuses of the nodes. - nodeToStatus map[string]*Status - // absentNodesStatus defines a status for all nodes that are absent in nodeToStatus map. - // By default, all absent nodes are UnschedulableAndUnresolvable. - absentNodesStatus *Status -} - -// NewDefaultNodeToStatus creates NodeToStatus without any node in the map. -// The absentNodesStatus is set by default to UnschedulableAndUnresolvable. -func NewDefaultNodeToStatus() *NodeToStatus { - return NewNodeToStatus(make(map[string]*Status), NewStatus(UnschedulableAndUnresolvable)) -} - -// NewNodeToStatus creates NodeToStatus initialized with given nodeToStatus and absentNodesStatus. -func NewNodeToStatus(nodeToStatus map[string]*Status, absentNodesStatus *Status) *NodeToStatus { - return &NodeToStatus{ - nodeToStatus: nodeToStatus, - absentNodesStatus: absentNodesStatus, - } -} - -// Get returns the status for given nodeName. If the node is not in the map, the absentNodesStatus is returned. -func (m *NodeToStatus) Get(nodeName string) *Status { - if status, ok := m.nodeToStatus[nodeName]; ok { - return status - } - return m.absentNodesStatus -} - -// Set sets status for given nodeName. -func (m *NodeToStatus) Set(nodeName string, status *Status) { - m.nodeToStatus[nodeName] = status -} - -// Len returns length of nodeToStatus map. It is not aware of number of absent nodes. -func (m *NodeToStatus) Len() int { - return len(m.nodeToStatus) -} - -// AbsentNodesStatus returns absentNodesStatus value. -func (m *NodeToStatus) AbsentNodesStatus() *Status { - return m.absentNodesStatus -} - -// SetAbsentNodesStatus sets absentNodesStatus value. -func (m *NodeToStatus) SetAbsentNodesStatus(status *Status) { - m.absentNodesStatus = status -} - -// ForEachExplicitNode runs fn for each node which status is explicitly set. -// Imporatant note, it runs the fn only for nodes with a status explicitly registered, -// and hence may not run the fn for all existing nodes. -// For example, if PreFilter rejects all Nodes, the scheduler would NOT set a failure status to every Node, -// but set a failure status as AbsentNodesStatus. -// You're supposed to get a status from AbsentNodesStatus(), and consider all other nodes that are rejected by them. -func (m *NodeToStatus) ForEachExplicitNode(fn func(nodeName string, status *Status)) { - for nodeName, status := range m.nodeToStatus { - fn(nodeName, status) - } -} - -// NodesForStatusCode returns a list of NodeInfos for the nodes that matches a given status code. -// If the absentNodesStatus matches the code, all existing nodes are fetched using nodeLister -// and filtered using NodeToStatus.Get. -// If the absentNodesStatus doesn't match the code, nodeToStatus map is used to create a list of nodes -// and nodeLister.Get is used to obtain NodeInfo for each. -func (m *NodeToStatus) NodesForStatusCode(nodeLister NodeInfoLister, code Code) ([]*NodeInfo, error) { - var resultNodes []*NodeInfo - - if m.AbsentNodesStatus().Code() == code { - allNodes, err := nodeLister.List() - if err != nil { - return nil, err - } - if m.Len() == 0 { - // All nodes are absent and status code is matching, so can return all nodes. - return allNodes, nil - } - // Need to find all the nodes that are absent or have a matching code using the allNodes. - for _, node := range allNodes { - nodeName := node.Node().Name - if status := m.Get(nodeName); status.Code() == code { - resultNodes = append(resultNodes, node) - } - } - return resultNodes, nil - } - - m.ForEachExplicitNode(func(nodeName string, status *Status) { - if status.Code() == code { - if nodeInfo, err := nodeLister.Get(nodeName); err == nil { - resultNodes = append(resultNodes, nodeInfo) - } - } - }) - - return resultNodes, nil -} - -// NodePluginScores is a struct with node name and scores for that node. -type NodePluginScores struct { - // Name is node name. - Name string - // Scores is scores from plugins and extenders. - Scores []PluginScore - // TotalScore is the total score in Scores. - TotalScore int64 -} - -// PluginScore is a struct with plugin/extender name and score. -type PluginScore struct { - // Name is the name of plugin or extender. - Name string - Score int64 -} - -// Code is the Status code/type which is returned from plugins. -type Code int - -// These are predefined codes used in a Status. -// Note: when you add a new status, you have to add it in `codes` slice below. -const ( - // Success means that plugin ran correctly and found pod schedulable. - // NOTE: A nil status is also considered as "Success". - Success Code = iota - // Error is one of the failures, used for internal plugin errors, unexpected input, etc. - // Plugin shouldn't return this code for expected failures, like Unschedulable. - // Since it's the unexpected failure, the scheduling queue registers the pod without unschedulable plugins. - // Meaning, the Pod will be requeued to activeQ/backoffQ soon. - Error - // Unschedulable is one of the failures, used when a plugin finds a pod unschedulable. - // If it's returned from PreFilter or Filter, the scheduler might attempt to - // run other postFilter plugins like preemption to get this pod scheduled. - // Use UnschedulableAndUnresolvable to make the scheduler skipping other postFilter plugins. - // The accompanying status message should explain why the pod is unschedulable. - // - // We regard the backoff as a penalty of wasting the scheduling cycle. - // When the scheduling queue requeues Pods, which was rejected with Unschedulable in the last scheduling, - // the Pod goes through backoff. - Unschedulable - // UnschedulableAndUnresolvable is used when a plugin finds a pod unschedulable and - // other postFilter plugins like preemption would not change anything. - // See the comment on PostFilter interface for more details about how PostFilter should handle this status. - // Plugins should return Unschedulable if it is possible that the pod can get scheduled - // after running other postFilter plugins. - // The accompanying status message should explain why the pod is unschedulable. - // - // We regard the backoff as a penalty of wasting the scheduling cycle. - // When the scheduling queue requeues Pods, which was rejected with UnschedulableAndUnresolvable in the last scheduling, - // the Pod goes through backoff. - UnschedulableAndUnresolvable - // Wait is used when a Permit plugin finds a pod scheduling should wait. - Wait - // Skip is used in the following scenarios: - // - when a Bind plugin chooses to skip binding. - // - when a PreFilter plugin returns Skip so that coupled Filter plugin/PreFilterExtensions() will be skipped. - // - when a PreScore plugin returns Skip so that coupled Score plugin will be skipped. - Skip - // Pending means that the scheduling process is finished successfully, - // but the plugin wants to stop the scheduling cycle/binding cycle here. - // - // For example, if your plugin has to notify the scheduling result to an external component, - // and wait for it to complete something **before** binding. - // It's different from when to return Unschedulable/UnschedulableAndUnresolvable, - // because in this case, the scheduler decides where the Pod can go successfully, - // but we need to wait for the external component to do something based on that scheduling result. - // - // We regard the backoff as a penalty of wasting the scheduling cycle. - // In the case of returning Pending, we cannot say the scheduling cycle is wasted - // because the scheduling result is used to proceed the Pod's scheduling forward, - // that particular scheduling cycle is failed though. - // So, Pods rejected by such reasons don't need to suffer a penalty (backoff). - // When the scheduling queue requeues Pods, which was rejected with Pending in the last scheduling, - // the Pod goes to activeQ directly ignoring backoff. - Pending -) - -// This list should be exactly the same as the codes iota defined above in the same order. -var codes = []string{"Success", "Error", "Unschedulable", "UnschedulableAndUnresolvable", "Wait", "Skip", "Pending"} - -func (c Code) String() string { - return codes[c] -} - -const ( - // MaxNodeScore is the maximum score a Score plugin is expected to return. - MaxNodeScore int64 = 100 - - // MinNodeScore is the minimum score a Score plugin is expected to return. - MinNodeScore int64 = 0 - - // MaxTotalScore is the maximum total score. - MaxTotalScore int64 = math.MaxInt64 -) - -// PodsToActivateKey is a reserved state key for stashing pods. -// If the stashed pods are present in unschedulablePods or backoffQ,they will be -// activated (i.e., moved to activeQ) in two phases: -// - end of a scheduling cycle if it succeeds (will be cleared from `PodsToActivate` if activated) -// - end of a binding cycle if it succeeds -var PodsToActivateKey StateKey = "kubernetes.io/pods-to-activate" - -// PodsToActivate stores pods to be activated. -type PodsToActivate struct { - sync.Mutex - // Map is keyed with namespaced pod name, and valued with the pod. - Map map[string]*v1.Pod -} - -// Clone just returns the same state. -func (s *PodsToActivate) Clone() StateData { - return s -} - -// NewPodsToActivate instantiates a PodsToActivate object. -func NewPodsToActivate() *PodsToActivate { - return &PodsToActivate{Map: make(map[string]*v1.Pod)} -} - -// Status indicates the result of running a plugin. It consists of a code, a -// message, (optionally) an error, and a plugin name it fails by. -// When the status code is not Success, the reasons should explain why. -// And, when code is Success, all the other fields should be empty. -// NOTE: A nil Status is also considered as Success. -type Status struct { - code Code - reasons []string - err error - // plugin is an optional field that records the plugin name causes this status. - // It's set by the framework when code is Unschedulable, UnschedulableAndUnresolvable or Pending. - plugin string -} - -func (s *Status) WithError(err error) *Status { - s.err = err - return s -} - -// Code returns code of the Status. -func (s *Status) Code() Code { - if s == nil { - return Success - } - return s.code -} - -// Message returns a concatenated message on reasons of the Status. -func (s *Status) Message() string { - if s == nil { - return "" - } - return strings.Join(s.Reasons(), ", ") -} - -// SetPlugin sets the given plugin name to s.plugin. -func (s *Status) SetPlugin(plugin string) { - s.plugin = plugin -} - -// WithPlugin sets the given plugin name to s.plugin, -// and returns the given status object. -func (s *Status) WithPlugin(plugin string) *Status { - s.SetPlugin(plugin) - return s -} - -// Plugin returns the plugin name which caused this status. -func (s *Status) Plugin() string { - return s.plugin -} - -// Reasons returns reasons of the Status. -func (s *Status) Reasons() []string { - if s.err != nil { - return append([]string{s.err.Error()}, s.reasons...) - } - return s.reasons -} - -// AppendReason appends given reason to the Status. -func (s *Status) AppendReason(reason string) { - s.reasons = append(s.reasons, reason) -} - -// IsSuccess returns true if and only if "Status" is nil or Code is "Success". -func (s *Status) IsSuccess() bool { - return s.Code() == Success -} - -// IsWait returns true if and only if "Status" is non-nil and its Code is "Wait". -func (s *Status) IsWait() bool { - return s.Code() == Wait -} - -// IsSkip returns true if and only if "Status" is non-nil and its Code is "Skip". -func (s *Status) IsSkip() bool { - return s.Code() == Skip -} - -// IsRejected returns true if "Status" is Unschedulable (Unschedulable, UnschedulableAndUnresolvable, or Pending). -func (s *Status) IsRejected() bool { - code := s.Code() - return code == Unschedulable || code == UnschedulableAndUnresolvable || code == Pending -} - -// AsError returns nil if the status is a success, a wait or a skip; otherwise returns an "error" object -// with a concatenated message on reasons of the Status. -func (s *Status) AsError() error { - if s.IsSuccess() || s.IsWait() || s.IsSkip() { - return nil - } - if s.err != nil { - return s.err - } - return errors.New(s.Message()) -} - -// Equal checks equality of two statuses. This is useful for testing with -// cmp.Equal. -func (s *Status) Equal(x *Status) bool { - if s == nil || x == nil { - return s.IsSuccess() && x.IsSuccess() - } - if s.code != x.code { - return false - } - if !cmp.Equal(s.err, x.err, cmpopts.EquateErrors()) { - return false - } - if !cmp.Equal(s.reasons, x.reasons) { - return false - } - return cmp.Equal(s.plugin, x.plugin) -} - -func (s *Status) String() string { - return s.Message() -} - -// NewStatus makes a Status out of the given arguments and returns its pointer. -func NewStatus(code Code, reasons ...string) *Status { - s := &Status{ - code: code, - reasons: reasons, - } - return s -} - -// AsStatus wraps an error in a Status. -func AsStatus(err error) *Status { - if err == nil { - return nil - } - return &Status{ - code: Error, - err: err, - } -} - -// WaitingPod represents a pod currently waiting in the permit phase. -type WaitingPod interface { - // GetPod returns a reference to the waiting pod. - GetPod() *v1.Pod - // GetPendingPlugins returns a list of pending Permit plugin's name. - GetPendingPlugins() []string - // Allow declares the waiting pod is allowed to be scheduled by the plugin named as "pluginName". - // If this is the last remaining plugin to allow, then a success signal is delivered - // to unblock the pod. - Allow(pluginName string) - // Reject declares the waiting pod unschedulable. - Reject(pluginName, msg string) -} - -// Plugin is the parent type for all the scheduling framework plugins. -type Plugin interface { - Name() string -} - -// PreEnqueuePlugin is an interface that must be implemented by "PreEnqueue" plugins. -// These plugins are called prior to adding Pods to activeQ. -// Note: an preEnqueue plugin is expected to be lightweight and efficient, so it's not expected to -// involve expensive calls like accessing external endpoints; otherwise it'd block other -// Pods' enqueuing in event handlers. -type PreEnqueuePlugin interface { - Plugin - // PreEnqueue is called prior to adding Pods to activeQ. - PreEnqueue(ctx context.Context, p *v1.Pod) *Status -} - -// LessFunc is the function to sort pod info -type LessFunc func(podInfo1, podInfo2 *QueuedPodInfo) bool - -// QueueSortPlugin is an interface that must be implemented by "QueueSort" plugins. -// These plugins are used to sort pods in the scheduling queue. Only one queue sort -// plugin may be enabled at a time. -type QueueSortPlugin interface { - Plugin - // Less are used to sort pods in the scheduling queue. - Less(*QueuedPodInfo, *QueuedPodInfo) bool -} - -// EnqueueExtensions is an optional interface that plugins can implement to efficiently -// move unschedulable Pods in internal scheduling queues. -// In the scheduler, Pods can be unschedulable by PreEnqueue, PreFilter, Filter, Reserve, and Permit plugins, -// and Pods rejected by these plugins are requeued based on this extension point. -// Failures from other extension points are regarded as temporal errors (e.g., network failure), -// and the scheduler requeue Pods without this extension point - always requeue Pods to activeQ after backoff. -// This is because such temporal errors cannot be resolved by specific cluster events, -// and we have no choose but keep retrying scheduling until the failure is resolved. -// -// Plugins that make pod unschedulable (PreEnqueue, PreFilter, Filter, Reserve, and Permit plugins) should implement this interface, -// otherwise the default implementation will be used, which is less efficient in requeueing Pods rejected by the plugin. -// And, if plugins other than above extension points support this interface, they are just ignored. -type EnqueueExtensions interface { - Plugin - // EventsToRegister returns a series of possible events that may cause a Pod - // failed by this plugin schedulable. Each event has a callback function that - // filters out events to reduce useless retry of Pod's scheduling. - // The events will be registered when instantiating the internal scheduling queue, - // and leveraged to build event handlers dynamically. - // When it returns an error, the scheduler fails to start. - // Note: the returned list needs to be determined at a startup, - // and the scheduler only evaluates it once during start up. - // Do not change the result during runtime, for example, based on the cluster's state etc. - // - // Appropriate implementation of this function will make Pod's re-scheduling accurate and performant. - EventsToRegister(context.Context) ([]ClusterEventWithHint, error) -} - -// PreFilterExtensions is an interface that is included in plugins that allow specifying -// callbacks to make incremental updates to its supposedly pre-calculated -// state. -type PreFilterExtensions interface { - // AddPod is called by the framework while trying to evaluate the impact - // of adding podToAdd to the node while scheduling podToSchedule. - AddPod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podInfoToAdd *PodInfo, nodeInfo *NodeInfo) *Status - // RemovePod is called by the framework while trying to evaluate the impact - // of removing podToRemove from the node while scheduling podToSchedule. - RemovePod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podInfoToRemove *PodInfo, nodeInfo *NodeInfo) *Status -} - -// PreFilterPlugin is an interface that must be implemented by "PreFilter" plugins. -// These plugins are called at the beginning of the scheduling cycle. -type PreFilterPlugin interface { - Plugin - // PreFilter is called at the beginning of the scheduling cycle. All PreFilter - // plugins must return success or the pod will be rejected. PreFilter could optionally - // return a PreFilterResult to influence which nodes to evaluate downstream. This is useful - // for cases where it is possible to determine the subset of nodes to process in O(1) time. - // When PreFilterResult filters out some Nodes, the framework considers Nodes that are filtered out as getting "UnschedulableAndUnresolvable". - // i.e., those Nodes will be out of the candidates of the preemption. - // - // When it returns Skip status, returned PreFilterResult and other fields in status are just ignored, - // and coupled Filter plugin/PreFilterExtensions() will be skipped in this scheduling cycle. - PreFilter(ctx context.Context, state *CycleState, p *v1.Pod) (*PreFilterResult, *Status) - // PreFilterExtensions returns a PreFilterExtensions interface if the plugin implements one, - // or nil if it does not. A Pre-filter plugin can provide extensions to incrementally - // modify its pre-processed info. The framework guarantees that the extensions - // AddPod/RemovePod will only be called after PreFilter, possibly on a cloned - // CycleState, and may call those functions more than once before calling - // Filter again on a specific node. - PreFilterExtensions() PreFilterExtensions -} - -// FilterPlugin is an interface for Filter plugins. These plugins are called at the -// filter extension point for filtering out hosts that cannot run a pod. -// This concept used to be called 'predicate' in the original scheduler. -// These plugins should return "Success", "Unschedulable" or "Error" in Status.code. -// However, the scheduler accepts other valid codes as well. -// Anything other than "Success" will lead to exclusion of the given host from -// running the pod. -type FilterPlugin interface { - Plugin - // Filter is called by the scheduling framework. - // All FilterPlugins should return "Success" to declare that - // the given node fits the pod. If Filter doesn't return "Success", - // it will return "Unschedulable", "UnschedulableAndUnresolvable" or "Error". - // - // "Error" aborts pod scheduling and puts the pod into the backoff queue. - // - // For the node being evaluated, Filter plugins should look at the passed - // nodeInfo reference for this particular node's information (e.g., pods - // considered to be running on the node) instead of looking it up in the - // NodeInfoSnapshot because we don't guarantee that they will be the same. - // For example, during preemption, we may pass a copy of the original - // nodeInfo object that has some pods removed from it to evaluate the - // possibility of preempting them to schedule the target pod. - Filter(ctx context.Context, state *CycleState, pod *v1.Pod, nodeInfo *NodeInfo) *Status -} - -// PostFilterPlugin is an interface for "PostFilter" plugins. These plugins are called -// after a pod cannot be scheduled. -type PostFilterPlugin interface { - Plugin - // PostFilter is called by the scheduling framework - // when the scheduling cycle failed at PreFilter or Filter by Unschedulable or UnschedulableAndUnresolvable. - // NodeToStatusReader has statuses that each Node got in PreFilter or Filter phase. - // - // If you're implementing a custom preemption with PostFilter, ignoring Nodes with UnschedulableAndUnresolvable is the responsibility of your plugin, - // meaning NodeToStatusReader could have Nodes with UnschedulableAndUnresolvable - // and the scheduling framework does call PostFilter plugins even when all Nodes in NodeToStatusReader are UnschedulableAndUnresolvable. - // - // A PostFilter plugin should return one of the following statuses: - // - Unschedulable: the plugin gets executed successfully but the pod cannot be made schedulable. - // - Success: the plugin gets executed successfully and the pod can be made schedulable. - // - Error: the plugin aborts due to some internal error. - // - // Informational plugins should be configured ahead of other ones, and always return Unschedulable status. - // Optionally, a non-nil PostFilterResult may be returned along with a Success status. For example, - // a preemption plugin may choose to return nominatedNodeName, so that framework can reuse that to update the - // preemptor pod's .spec.status.nominatedNodeName field. - PostFilter(ctx context.Context, state *CycleState, pod *v1.Pod, filteredNodeStatusMap NodeToStatusReader) (*PostFilterResult, *Status) -} - -// PreScorePlugin is an interface for "PreScore" plugin. PreScore is an -// informational extension point. Plugins will be called with a list of nodes -// that passed the filtering phase. A plugin may use this data to update internal -// state or to generate logs/metrics. -type PreScorePlugin interface { - Plugin - // PreScore is called by the scheduling framework after a list of nodes - // passed the filtering phase. All prescore plugins must return success or - // the pod will be rejected - // When it returns Skip status, other fields in status are just ignored, - // and coupled Score plugin will be skipped in this scheduling cycle. - PreScore(ctx context.Context, state *CycleState, pod *v1.Pod, nodes []*NodeInfo) *Status -} - -// ScoreExtensions is an interface for Score extended functionality. -type ScoreExtensions interface { - // NormalizeScore is called for all node scores produced by the same plugin's "Score" - // method. A successful run of NormalizeScore will update the scores list and return - // a success status. - NormalizeScore(ctx context.Context, state *CycleState, p *v1.Pod, scores NodeScoreList) *Status -} - -// ScorePlugin is an interface that must be implemented by "Score" plugins to rank -// nodes that passed the filtering phase. -type ScorePlugin interface { - Plugin - // Score is called on each filtered node. It must return success and an integer - // indicating the rank of the node. All scoring plugins must return success or - // the pod will be rejected. - Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeInfo *NodeInfo) (int64, *Status) - - // ScoreExtensions returns a ScoreExtensions interface if it implements one, or nil if does not. - ScoreExtensions() ScoreExtensions -} - -// ReservePlugin is an interface for plugins with Reserve and Unreserve -// methods. These are meant to update the state of the plugin. This concept -// used to be called 'assume' in the original scheduler. These plugins should -// return only Success or Error in Status.code. However, the scheduler accepts -// other valid codes as well. Anything other than Success will lead to -// rejection of the pod. -type ReservePlugin interface { - Plugin - // Reserve is called by the scheduling framework when the scheduler cache is - // updated. If this method returns a failed Status, the scheduler will call - // the Unreserve method for all enabled ReservePlugins. - Reserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status - // Unreserve is called by the scheduling framework when a reserved pod was - // rejected, an error occurred during reservation of subsequent plugins, or - // in a later phase. The Unreserve method implementation must be idempotent - // and may be called by the scheduler even if the corresponding Reserve - // method for the same plugin was not called. - Unreserve(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) -} - -// PreBindPlugin is an interface that must be implemented by "PreBind" plugins. -// These plugins are called before a pod being scheduled. -type PreBindPlugin interface { - Plugin - // PreBind is called before binding a pod. All prebind plugins must return - // success or the pod will be rejected and won't be sent for binding. - PreBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status -} - -// PostBindPlugin is an interface that must be implemented by "PostBind" plugins. -// These plugins are called after a pod is successfully bound to a node. -type PostBindPlugin interface { - Plugin - // PostBind is called after a pod is successfully bound. These plugins are - // informational. A common application of this extension point is for cleaning - // up. If a plugin needs to clean-up its state after a pod is scheduled and - // bound, PostBind is the extension point that it should register. - PostBind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) -} - -// PermitPlugin is an interface that must be implemented by "Permit" plugins. -// These plugins are called before a pod is bound to a node. -type PermitPlugin interface { - Plugin - // Permit is called before binding a pod (and before prebind plugins). Permit - // plugins are used to prevent or delay the binding of a Pod. A permit plugin - // must return success or wait with timeout duration, or the pod will be rejected. - // The pod will also be rejected if the wait timeout or the pod is rejected while - // waiting. Note that if the plugin returns "wait", the framework will wait only - // after running the remaining plugins given that no other plugin rejects the pod. - Permit(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (*Status, time.Duration) -} - -// BindPlugin is an interface that must be implemented by "Bind" plugins. Bind -// plugins are used to bind a pod to a Node. -type BindPlugin interface { - Plugin - // Bind plugins will not be called until all pre-bind plugins have completed. Each - // bind plugin is called in the configured order. A bind plugin may choose whether - // or not to handle the given Pod. If a bind plugin chooses to handle a Pod, the - // remaining bind plugins are skipped. When a bind plugin does not handle a pod, - // it must return Skip in its Status code. If a bind plugin returns an Error, the - // pod is rejected and will not be bound. - Bind(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) *Status -} - -// Framework manages the set of plugins in use by the scheduling framework. -// Configured plugins are called at specified points in a scheduling context. -type Framework interface { - Handle - - // PreEnqueuePlugins returns the registered preEnqueue plugins. - PreEnqueuePlugins() []PreEnqueuePlugin - - // EnqueueExtensions returns the registered Enqueue extensions. - EnqueueExtensions() []EnqueueExtensions - - // QueueSortFunc returns the function to sort pods in scheduling queue - QueueSortFunc() LessFunc - - // RunPreFilterPlugins runs the set of configured PreFilter plugins. It returns - // *Status and its code is set to non-success if any of the plugins returns - // anything but Success. If a non-success status is returned, then the scheduling - // cycle is aborted. - // It also returns a PreFilterResult, which may influence what or how many nodes to - // evaluate downstream. - // The third returns value contains PreFilter plugin that rejected some or all Nodes with PreFilterResult. - // But, note that it doesn't contain any plugin when a plugin rejects this Pod with non-success status, - // not with PreFilterResult. - RunPreFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod) (*PreFilterResult, *Status, sets.Set[string]) - - // RunPostFilterPlugins runs the set of configured PostFilter plugins. - // PostFilter plugins can either be informational, in which case should be configured - // to execute first and return Unschedulable status, or ones that try to change the - // cluster state to make the pod potentially schedulable in a future scheduling cycle. - RunPostFilterPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, filteredNodeStatusMap NodeToStatusReader) (*PostFilterResult, *Status) - - // RunPreBindPlugins runs the set of configured PreBind plugins. It returns - // *Status and its code is set to non-success if any of the plugins returns - // anything but Success. If the Status code is "Unschedulable", it is - // considered as a scheduling check failure, otherwise, it is considered as an - // internal error. In either case the pod is not going to be bound. - RunPreBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status - - // RunPostBindPlugins runs the set of configured PostBind plugins. - RunPostBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) - - // RunReservePluginsReserve runs the Reserve method of the set of - // configured Reserve plugins. If any of these calls returns an error, it - // does not continue running the remaining ones and returns the error. In - // such case, pod will not be scheduled. - RunReservePluginsReserve(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status - - // RunReservePluginsUnreserve runs the Unreserve method of the set of - // configured Reserve plugins. - RunReservePluginsUnreserve(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) - - // RunPermitPlugins runs the set of configured Permit plugins. If any of these - // plugins returns a status other than "Success" or "Wait", it does not continue - // running the remaining plugins and returns an error. Otherwise, if any of the - // plugins returns "Wait", then this function will create and add waiting pod - // to a map of currently waiting pods and return status with "Wait" code. - // Pod will remain waiting pod for the minimum duration returned by the Permit plugins. - RunPermitPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status - - // WaitOnPermit will block, if the pod is a waiting pod, until the waiting pod is rejected or allowed. - WaitOnPermit(ctx context.Context, pod *v1.Pod) *Status - - // RunBindPlugins runs the set of configured Bind plugins. A Bind plugin may choose - // whether or not to handle the given Pod. If a Bind plugin chooses to skip the - // binding, it should return code=5("skip") status. Otherwise, it should return "Error" - // or "Success". If none of the plugins handled binding, RunBindPlugins returns - // code=5("skip") status. - RunBindPlugins(ctx context.Context, state *CycleState, pod *v1.Pod, nodeName string) *Status - - // HasFilterPlugins returns true if at least one Filter plugin is defined. - HasFilterPlugins() bool - - // HasPostFilterPlugins returns true if at least one PostFilter plugin is defined. - HasPostFilterPlugins() bool - - // HasScorePlugins returns true if at least one Score plugin is defined. - HasScorePlugins() bool - - // ListPlugins returns a map of extension point name to list of configured Plugins. - ListPlugins() *config.Plugins - - // ProfileName returns the profile name associated to a profile. - ProfileName() string - - // PercentageOfNodesToScore returns percentageOfNodesToScore associated to a profile. - PercentageOfNodesToScore() *int32 - - // SetPodNominator sets the PodNominator - SetPodNominator(nominator PodNominator) - // SetPodActivator sets the PodActivator - SetPodActivator(activator PodActivator) - - // Close calls Close method of each plugin. - Close() error -} - -// Handle provides data and some tools that plugins can use. It is -// passed to the plugin factories at the time of plugin initialization. Plugins -// must store and use this handle to call framework functions. -type Handle interface { - // PodNominator abstracts operations to maintain nominated Pods. - PodNominator - // PluginsRunner abstracts operations to run some plugins. - PluginsRunner - // PodActivator abstracts operations in the scheduling queue. - PodActivator - // SnapshotSharedLister returns listers from the latest NodeInfo Snapshot. The snapshot - // is taken at the beginning of a scheduling cycle and remains unchanged until - // a pod finishes "Permit" point. - // - // It should be used only during scheduling cycle: - // - There is no guarantee that the information remains unchanged in the binding phase of scheduling. - // So, plugins shouldn't use it in the binding cycle (pre-bind/bind/post-bind/un-reserve plugin) - // otherwise, a concurrent read/write error might occur. - // - There is no guarantee that the information is always up-to-date. - // So, plugins shouldn't use it in QueueingHint and PreEnqueue - // otherwise, they might make a decision based on stale information. - // - // Instead, they should use the resources getting from Informer created from SharedInformerFactory(). - SnapshotSharedLister() SharedLister - - // IterateOverWaitingPods acquires a read lock and iterates over the WaitingPods map. - IterateOverWaitingPods(callback func(WaitingPod)) - - // GetWaitingPod returns a waiting pod given its UID. - GetWaitingPod(uid types.UID) WaitingPod - - // RejectWaitingPod rejects a waiting pod given its UID. - // The return value indicates if the pod is waiting or not. - RejectWaitingPod(uid types.UID) bool - - // ClientSet returns a kubernetes clientSet. - ClientSet() clientset.Interface - - // KubeConfig returns the raw kube config. - KubeConfig() *restclient.Config - - // EventRecorder returns an event recorder. - EventRecorder() events.EventRecorder - - SharedInformerFactory() informers.SharedInformerFactory - - // SharedDRAManager can be used to obtain DRA objects, and track modifications to them in-memory - mainly by the DRA plugin. - // A non-default implementation can be plugged into the framework to simulate the state of DRA objects. - SharedDRAManager() SharedDRAManager - - // RunFilterPluginsWithNominatedPods runs the set of configured filter plugins for nominated pod on the given node. - RunFilterPluginsWithNominatedPods(ctx context.Context, state *CycleState, pod *v1.Pod, info *NodeInfo) *Status - - // Extenders returns registered scheduler extenders. - Extenders() []Extender - - // Parallelizer returns a parallelizer holding parallelism for scheduler. - Parallelizer() parallelize.Parallelizer -} - -// PreFilterResult wraps needed info for scheduler framework to act upon PreFilter phase. -type PreFilterResult struct { - // The set of nodes that should be considered downstream; if nil then - // all nodes are eligible. - NodeNames sets.Set[string] -} - -func (p *PreFilterResult) AllNodes() bool { - return p == nil || p.NodeNames == nil -} - -func (p *PreFilterResult) Merge(in *PreFilterResult) *PreFilterResult { - if p.AllNodes() && in.AllNodes() { - return nil - } - - r := PreFilterResult{} - if p.AllNodes() { - r.NodeNames = in.NodeNames.Clone() - return &r - } - if in.AllNodes() { - r.NodeNames = p.NodeNames.Clone() - return &r - } - - r.NodeNames = p.NodeNames.Intersection(in.NodeNames) - return &r -} - -type NominatingMode int - -const ( - ModeNoop NominatingMode = iota - ModeOverride -) - -type NominatingInfo struct { - NominatedNodeName string - NominatingMode NominatingMode -} - -// PostFilterResult wraps needed info for scheduler framework to act upon PostFilter phase. -type PostFilterResult struct { - *NominatingInfo -} - -func NewPostFilterResultWithNominatedNode(name string) *PostFilterResult { - return &PostFilterResult{ - NominatingInfo: &NominatingInfo{ - NominatedNodeName: name, - NominatingMode: ModeOverride, - }, - } -} - -func (ni *NominatingInfo) Mode() NominatingMode { - if ni == nil { - return ModeNoop - } - return ni.NominatingMode -} - -// PodActivator abstracts operations in the scheduling queue. -type PodActivator interface { - // Activate moves the given pods to activeQ. - // If a pod isn't found in unschedulablePods or backoffQ and it's in-flight, - // the wildcard event is registered so that the pod will be requeued when it comes back. - // But, if a pod isn't found in unschedulablePods or backoffQ and it's not in-flight (i.e., completely unknown pod), - // Activate would ignore the pod. - Activate(logger klog.Logger, pods map[string]*v1.Pod) -} - -// PodNominator abstracts operations to maintain nominated Pods. -type PodNominator interface { - // AddNominatedPod adds the given pod to the nominator or - // updates it if it already exists. - AddNominatedPod(logger klog.Logger, pod *PodInfo, nominatingInfo *NominatingInfo) - // DeleteNominatedPodIfExists deletes nominatedPod from internal cache. It's a no-op if it doesn't exist. - DeleteNominatedPodIfExists(pod *v1.Pod) - // UpdateNominatedPod updates the with . - UpdateNominatedPod(logger klog.Logger, oldPod *v1.Pod, newPodInfo *PodInfo) - // NominatedPodsForNode returns nominatedPods on the given node. - NominatedPodsForNode(nodeName string) []*PodInfo -} - -// PluginsRunner abstracts operations to run some plugins. -// This is used by preemption PostFilter plugins when evaluating the feasibility of -// scheduling the pod on nodes when certain running pods get evicted. -type PluginsRunner interface { - // RunPreScorePlugins runs the set of configured PreScore plugins. If any - // of these plugins returns any status other than "Success", the given pod is rejected. - RunPreScorePlugins(context.Context, *CycleState, *v1.Pod, []*NodeInfo) *Status - // RunScorePlugins runs the set of configured scoring plugins. - // It returns a list that stores scores from each plugin and total score for each Node. - // It also returns *Status, which is set to non-success if any of the plugins returns - // a non-success status. - RunScorePlugins(context.Context, *CycleState, *v1.Pod, []*NodeInfo) ([]NodePluginScores, *Status) - // RunFilterPlugins runs the set of configured Filter plugins for pod on - // the given node. Note that for the node being evaluated, the passed nodeInfo - // reference could be different from the one in NodeInfoSnapshot map (e.g., pods - // considered to be running on the node could be different). For example, during - // preemption, we may pass a copy of the original nodeInfo object that has some pods - // removed from it to evaluate the possibility of preempting them to - // schedule the target pod. - RunFilterPlugins(context.Context, *CycleState, *v1.Pod, *NodeInfo) *Status - // RunPreFilterExtensionAddPod calls the AddPod interface for the set of configured - // PreFilter plugins. It returns directly if any of the plugins return any - // status other than Success. - RunPreFilterExtensionAddPod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podInfoToAdd *PodInfo, nodeInfo *NodeInfo) *Status - // RunPreFilterExtensionRemovePod calls the RemovePod interface for the set of configured - // PreFilter plugins. It returns directly if any of the plugins return any - // status other than Success. - RunPreFilterExtensionRemovePod(ctx context.Context, state *CycleState, podToSchedule *v1.Pod, podInfoToRemove *PodInfo, nodeInfo *NodeInfo) *Status -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/listers.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/listers.go deleted file mode 100644 index e56266ba1..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/listers.go +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package framework - -import ( - resourceapi "k8s.io/api/resource/v1beta1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/dynamic-resource-allocation/structured" -) - -// NodeInfoLister interface represents anything that can list/get NodeInfo objects from node name. -type NodeInfoLister interface { - // List returns the list of NodeInfos. - List() ([]*NodeInfo, error) - // HavePodsWithAffinityList returns the list of NodeInfos of nodes with pods with affinity terms. - HavePodsWithAffinityList() ([]*NodeInfo, error) - // HavePodsWithRequiredAntiAffinityList returns the list of NodeInfos of nodes with pods with required anti-affinity terms. - HavePodsWithRequiredAntiAffinityList() ([]*NodeInfo, error) - // Get returns the NodeInfo of the given node name. - Get(nodeName string) (*NodeInfo, error) -} - -// StorageInfoLister interface represents anything that handles storage-related operations and resources. -type StorageInfoLister interface { - // IsPVCUsedByPods returns true/false on whether the PVC is used by one or more scheduled pods, - // keyed in the format "namespace/name". - IsPVCUsedByPods(key string) bool -} - -// SharedLister groups scheduler-specific listers. -type SharedLister interface { - NodeInfos() NodeInfoLister - StorageInfos() StorageInfoLister -} - -// ResourceSliceLister can be used to obtain ResourceSlices. -type ResourceSliceLister interface { - // ListWithDeviceTaintRules returns a list of all ResourceSlices with DeviceTaintRules applied - // if the DRADeviceTaints feature is enabled, otherwise without them. - // - // k8s.io/dynamic-resource-allocation/resourceslice/tracker provides an implementation - // of the necessary logic. That tracker can be instantiated as a replacement for - // a normal ResourceSlice informer and provides a ListPatchedResourceSlices method. - ListWithDeviceTaintRules() ([]*resourceapi.ResourceSlice, error) -} - -// DeviceClassLister can be used to obtain DeviceClasses. -type DeviceClassLister interface { - // List returns a list of all DeviceClasses. - List() ([]*resourceapi.DeviceClass, error) - // Get returns the DeviceClass with the given className. - Get(className string) (*resourceapi.DeviceClass, error) -} - -// ResourceClaimTracker can be used to obtain ResourceClaims, and track changes to ResourceClaims in-memory. -// -// If the claims are meant to be allocated in the API during the binding phase (when used by scheduler), the tracker helps avoid -// race conditions between scheduling and binding phases (as well as between the binding phase and the informer cache update). -// -// If the binding phase is not run (e.g. when used by Cluster Autoscaler which only runs the scheduling phase, and simulates binding in-memory), -// the tracker allows the framework user to obtain the claim allocations produced by the DRA plugin, and persist them outside of the API (e.g. in-memory). -type ResourceClaimTracker interface { - // List lists ResourceClaims. The result is guaranteed to immediately include any changes made via AssumeClaimAfterAPICall(), - // and SignalClaimPendingAllocation(). - List() ([]*resourceapi.ResourceClaim, error) - // Get works like List(), but for a single claim. - Get(namespace, claimName string) (*resourceapi.ResourceClaim, error) - // ListAllAllocatedDevices lists all allocated Devices from allocated ResourceClaims. The result is guaranteed to immediately include - // any changes made via AssumeClaimAfterAPICall(), and SignalClaimPendingAllocation(). - ListAllAllocatedDevices() (sets.Set[structured.DeviceID], error) - - // SignalClaimPendingAllocation signals to the tracker that the given ResourceClaim will be allocated via an API call in the - // binding phase. This change is immediately reflected in the result of List() and the other accessors. - SignalClaimPendingAllocation(claimUID types.UID, allocatedClaim *resourceapi.ResourceClaim) error - // ClaimHasPendingAllocation answers whether a given claim has a pending allocation during the binding phase. It can be used to avoid - // race conditions in subsequent scheduling phases. - ClaimHasPendingAllocation(claimUID types.UID) bool - // RemoveClaimPendingAllocation removes the pending allocation for the given ResourceClaim from the tracker if any was signaled via - // SignalClaimPendingAllocation(). Returns whether there was a pending allocation to remove. List() and the other accessors immediately - // stop reflecting the pending allocation in the results. - RemoveClaimPendingAllocation(claimUID types.UID) (deleted bool) - - // AssumeClaimAfterAPICall signals to the tracker that an API call modifying the given ResourceClaim was made in the binding phase, and the - // changes should be reflected in informers very soon. This change is immediately reflected in the result of List() and the other accessors. - // This mechanism can be used to avoid race conditions between the informer update and subsequent scheduling phases. - AssumeClaimAfterAPICall(claim *resourceapi.ResourceClaim) error - // AssumedClaimRestore signals to the tracker that something went wrong with the API call modifying the given ResourceClaim, and - // the changes won't be reflected in informers after all. List() and the other accessors immediately stop reflecting the assumed change, - // and go back to the informer version. - AssumedClaimRestore(namespace, claimName string) -} - -// SharedDRAManager can be used to obtain DRA objects, and track modifications to them in-memory - mainly by the DRA plugin. -// The plugin's default implementation obtains the objects from the API. A different implementation can be -// plugged into the framework in order to simulate the state of DRA objects. For example, Cluster Autoscaler -// can use this to provide the correct DRA object state to the DRA plugin when simulating scheduling changes in-memory. -type SharedDRAManager interface { - ResourceClaims() ResourceClaimTracker - ResourceSlices() ResourceSliceLister - DeviceClasses() DeviceClassLister -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go deleted file mode 100644 index 2eff825ba..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/error_channel.go +++ /dev/null @@ -1,59 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package parallelize - -import "context" - -// ErrorChannel supports non-blocking send and receive operation to capture error. -// A maximum of one error is kept in the channel and the rest of the errors sent -// are ignored, unless the existing error is received and the channel becomes empty -// again. -type ErrorChannel struct { - errCh chan error -} - -// SendError sends an error without blocking the sender. -func (e *ErrorChannel) SendError(err error) { - select { - case e.errCh <- err: - default: - } -} - -// SendErrorWithCancel sends an error without blocking the sender and calls -// cancel function. -func (e *ErrorChannel) SendErrorWithCancel(err error, cancel context.CancelFunc) { - e.SendError(err) - cancel() -} - -// ReceiveError receives an error from channel without blocking on the receiver. -func (e *ErrorChannel) ReceiveError() error { - select { - case err := <-e.errCh: - return err - default: - return nil - } -} - -// NewErrorChannel returns a new ErrorChannel. -func NewErrorChannel() *ErrorChannel { - return &ErrorChannel{ - errCh: make(chan error, 1), - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/parallelism.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/parallelism.go deleted file mode 100644 index 2ac14289a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/parallelize/parallelism.go +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package parallelize - -import ( - "context" - "math" - - "k8s.io/client-go/util/workqueue" - "k8s.io/kubernetes/pkg/scheduler/metrics" -) - -// DefaultParallelism is the default parallelism used in scheduler. -const DefaultParallelism int = 16 - -// Parallelizer holds the parallelism for scheduler. -type Parallelizer struct { - parallelism int -} - -// NewParallelizer returns an object holding the parallelism. -func NewParallelizer(p int) Parallelizer { - return Parallelizer{parallelism: p} -} - -// chunkSizeFor returns a chunk size for the given number of items to use for -// parallel work. The size aims to produce good CPU utilization. -// returns max(1, min(sqrt(n), n/Parallelism)) -func chunkSizeFor(n, parallelism int) int { - s := int(math.Sqrt(float64(n))) - - if r := n/parallelism + 1; s > r { - s = r - } else if s < 1 { - s = 1 - } - return s -} - -// numWorkersForChunkSize returns number of workers (goroutines) -// that will be created in workqueue.ParallelizeUntil -// for given parallelism, pieces and chunkSize values. -func numWorkersForChunkSize(parallelism, pieces, chunkSize int) int { - chunks := (pieces + chunkSize - 1) / chunkSize - if chunks < parallelism { - return chunks - } - return parallelism -} - -// Until is a wrapper around workqueue.ParallelizeUntil to use in scheduling algorithms. -// A given operation will be a label that is recorded in the goroutine metric. -func (p Parallelizer) Until(ctx context.Context, pieces int, doWorkPiece workqueue.DoWorkPieceFunc, operation string) { - chunkSize := chunkSizeFor(pieces, p.parallelism) - workers := numWorkersForChunkSize(p.parallelism, pieces, chunkSize) - - goroutinesMetric := metrics.Goroutines.WithLabelValues(operation) - // Calling single Add with workers' count is more efficient than calling Inc or Dec per each work piece. - // This approach improves performance of some plugins (affinity, topology spreading) as well as preemption. - goroutinesMetric.Add(float64(workers)) - defer goroutinesMetric.Add(float64(-workers)) - - workqueue.ParallelizeUntil(ctx, p.parallelism, pieces, doWorkPiece, workqueue.WithChunkSize(chunkSize)) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/README.md b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/README.md deleted file mode 100644 index 6fba8bb84..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Scheduler Framework Plugins - -Moved [here](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduler_framework_plugins.md). diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder/default_binder.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder/default_binder.go deleted file mode 100644 index aa1ed6a69..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder/default_binder.go +++ /dev/null @@ -1,63 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package defaultbinder - -import ( - "context" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" -) - -// Name of the plugin used in the plugin registry and configurations. -const Name = names.DefaultBinder - -// DefaultBinder binds pods to nodes using a k8s client. -type DefaultBinder struct { - handle framework.Handle -} - -var _ framework.BindPlugin = &DefaultBinder{} - -// New creates a DefaultBinder. -func New(_ context.Context, _ runtime.Object, handle framework.Handle) (framework.Plugin, error) { - return &DefaultBinder{handle: handle}, nil -} - -// Name returns the name of the plugin. -func (b DefaultBinder) Name() string { - return Name -} - -// Bind binds pods to nodes using the k8s client. -func (b DefaultBinder) Bind(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) *framework.Status { - logger := klog.FromContext(ctx) - logger.V(3).Info("Attempting to bind pod to node", "pod", klog.KObj(p), "node", klog.KRef("", nodeName)) - binding := &v1.Binding{ - ObjectMeta: metav1.ObjectMeta{Namespace: p.Namespace, Name: p.Name, UID: p.UID}, - Target: v1.ObjectReference{Kind: "Node", Name: nodeName}, - } - err := b.handle.ClientSet().CoreV1().Pods(binding.Namespace).Bind(ctx, binding, metav1.CreateOptions{}) - if err != nil { - return framework.AsStatus(err) - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go deleted file mode 100644 index c36528530..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption/default_preemption.go +++ /dev/null @@ -1,368 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package defaultpreemption - -import ( - "context" - "fmt" - "math/rand" - "sort" - - v1 "k8s.io/api/core/v1" - policy "k8s.io/api/policy/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/informers" - corelisters "k8s.io/client-go/listers/core/v1" - policylisters "k8s.io/client-go/listers/policy/v1" - corev1helpers "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/klog/v2" - extenderv1 "k8s.io/kube-scheduler/extender/v1" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/framework/preemption" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// Name of the plugin used in the plugin registry and configurations. -const Name = names.DefaultPreemption - -// DefaultPreemption is a PostFilter plugin implements the preemption logic. -type DefaultPreemption struct { - fh framework.Handle - fts feature.Features - args config.DefaultPreemptionArgs - podLister corelisters.PodLister - pdbLister policylisters.PodDisruptionBudgetLister - Evaluator *preemption.Evaluator -} - -var _ framework.PostFilterPlugin = &DefaultPreemption{} -var _ framework.PreEnqueuePlugin = &DefaultPreemption{} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *DefaultPreemption) Name() string { - return Name -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, dpArgs runtime.Object, fh framework.Handle, fts feature.Features) (framework.Plugin, error) { - args, ok := dpArgs.(*config.DefaultPreemptionArgs) - if !ok { - return nil, fmt.Errorf("got args of type %T, want *DefaultPreemptionArgs", dpArgs) - } - if err := validation.ValidateDefaultPreemptionArgs(nil, args); err != nil { - return nil, err - } - - podLister := fh.SharedInformerFactory().Core().V1().Pods().Lister() - pdbLister := getPDBLister(fh.SharedInformerFactory()) - - pl := DefaultPreemption{ - fh: fh, - fts: fts, - args: *args, - podLister: podLister, - pdbLister: pdbLister, - } - pl.Evaluator = preemption.NewEvaluator(Name, fh, &pl, fts.EnableAsyncPreemption) - - return &pl, nil -} - -// PostFilter invoked at the postFilter extension point. -func (pl *DefaultPreemption) PostFilter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, m framework.NodeToStatusReader) (*framework.PostFilterResult, *framework.Status) { - defer func() { - metrics.PreemptionAttempts.Inc() - }() - - result, status := pl.Evaluator.Preempt(ctx, state, pod, m) - msg := status.Message() - if len(msg) > 0 { - return result, framework.NewStatus(status.Code(), "preemption: "+msg) - } - return result, status -} - -func (pl *DefaultPreemption) PreEnqueue(ctx context.Context, p *v1.Pod) *framework.Status { - if !pl.fts.EnableAsyncPreemption { - return nil - } - if pl.Evaluator.IsPodRunningPreemption(p.GetUID()) { - return framework.NewStatus(framework.UnschedulableAndUnresolvable, "waiting for the preemption for this pod to be finished") - } - return nil -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *DefaultPreemption) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // The plugin moves the preemptor Pod to acviteQ/backoffQ once the preemption API calls are all done, - // and we don't need to move the Pod with any events. - return nil, nil -} - -// calculateNumCandidates returns the number of candidates the FindCandidates -// method must produce from dry running based on the constraints given by -// and . The number of -// candidates returned will never be greater than . -func (pl *DefaultPreemption) calculateNumCandidates(numNodes int32) int32 { - n := (numNodes * pl.args.MinCandidateNodesPercentage) / 100 - if n < pl.args.MinCandidateNodesAbsolute { - n = pl.args.MinCandidateNodesAbsolute - } - if n > numNodes { - n = numNodes - } - return n -} - -// getOffsetRand is a dedicated random source for GetOffsetAndNumCandidates calls. -// It defaults to rand.Int31n, but is a package variable so it can be overridden to make unit tests deterministic. -var getOffsetRand = rand.Int31n - -// GetOffsetAndNumCandidates chooses a random offset and calculates the number -// of candidates that should be shortlisted for dry running preemption. -func (pl *DefaultPreemption) GetOffsetAndNumCandidates(numNodes int32) (int32, int32) { - return getOffsetRand(numNodes), pl.calculateNumCandidates(numNodes) -} - -// This function is not applicable for out-of-tree preemption plugins that exercise -// different preemption candidates on the same nominated node. -func (pl *DefaultPreemption) CandidatesToVictimsMap(candidates []preemption.Candidate) map[string]*extenderv1.Victims { - m := make(map[string]*extenderv1.Victims, len(candidates)) - for _, c := range candidates { - m[c.Name()] = c.Victims() - } - return m -} - -// SelectVictimsOnNode finds minimum set of pods on the given node that should be preempted in order to make enough room -// for "pod" to be scheduled. -func (pl *DefaultPreemption) SelectVictimsOnNode( - ctx context.Context, - state *framework.CycleState, - pod *v1.Pod, - nodeInfo *framework.NodeInfo, - pdbs []*policy.PodDisruptionBudget) ([]*v1.Pod, int, *framework.Status) { - logger := klog.FromContext(ctx) - var potentialVictims []*framework.PodInfo - removePod := func(rpi *framework.PodInfo) error { - if err := nodeInfo.RemovePod(logger, rpi.Pod); err != nil { - return err - } - status := pl.fh.RunPreFilterExtensionRemovePod(ctx, state, pod, rpi, nodeInfo) - if !status.IsSuccess() { - return status.AsError() - } - return nil - } - addPod := func(api *framework.PodInfo) error { - nodeInfo.AddPodInfo(api) - status := pl.fh.RunPreFilterExtensionAddPod(ctx, state, pod, api, nodeInfo) - if !status.IsSuccess() { - return status.AsError() - } - return nil - } - // As the first step, remove all the lower priority pods from the node and - // check if the given pod can be scheduled. - podPriority := corev1helpers.PodPriority(pod) - for _, pi := range nodeInfo.Pods { - if corev1helpers.PodPriority(pi.Pod) < podPriority { - potentialVictims = append(potentialVictims, pi) - if err := removePod(pi); err != nil { - return nil, 0, framework.AsStatus(err) - } - } - } - - // No potential victims are found, and so we don't need to evaluate the node again since its state didn't change. - if len(potentialVictims) == 0 { - return nil, 0, framework.NewStatus(framework.UnschedulableAndUnresolvable, "No preemption victims found for incoming pod") - } - - // If the new pod does not fit after removing all the lower priority pods, - // we are almost done and this node is not suitable for preemption. The only - // condition that we could check is if the "pod" is failing to schedule due to - // inter-pod affinity to one or more victims, but we have decided not to - // support this case for performance reasons. Having affinity to lower - // priority pods is not a recommended configuration anyway. - if status := pl.fh.RunFilterPluginsWithNominatedPods(ctx, state, pod, nodeInfo); !status.IsSuccess() { - return nil, 0, status - } - var victims []*v1.Pod - numViolatingVictim := 0 - // Sort potentialVictims by pod priority from high to low, which ensures to - // reprieve higher priority pods first. - sort.Slice(potentialVictims, func(i, j int) bool { return util.MoreImportantPod(potentialVictims[i].Pod, potentialVictims[j].Pod) }) - // Try to reprieve as many pods as possible. We first try to reprieve the PDB - // violating victims and then other non-violating ones. In both cases, we start - // from the highest priority victims. - violatingVictims, nonViolatingVictims := filterPodsWithPDBViolation(potentialVictims, pdbs) - reprievePod := func(pi *framework.PodInfo) (bool, error) { - if err := addPod(pi); err != nil { - return false, err - } - status := pl.fh.RunFilterPluginsWithNominatedPods(ctx, state, pod, nodeInfo) - fits := status.IsSuccess() - if !fits { - if err := removePod(pi); err != nil { - return false, err - } - rpi := pi.Pod - victims = append(victims, rpi) - logger.V(5).Info("Pod is a potential preemption victim on node", "pod", klog.KObj(rpi), "node", klog.KObj(nodeInfo.Node())) - } - return fits, nil - } - for _, p := range violatingVictims { - if fits, err := reprievePod(p); err != nil { - return nil, 0, framework.AsStatus(err) - } else if !fits { - numViolatingVictim++ - } - } - // Now we try to reprieve non-violating victims. - for _, p := range nonViolatingVictims { - if _, err := reprievePod(p); err != nil { - return nil, 0, framework.AsStatus(err) - } - } - - // Sort victims after reprieving pods to keep the pods in the victims sorted in order of priority from high to low. - if len(violatingVictims) != 0 && len(nonViolatingVictims) != 0 { - sort.Slice(victims, func(i, j int) bool { return util.MoreImportantPod(victims[i], victims[j]) }) - } - return victims, numViolatingVictim, framework.NewStatus(framework.Success) -} - -// PodEligibleToPreemptOthers returns one bool and one string. The bool -// indicates whether this pod should be considered for preempting other pods or -// not. The string includes the reason if this pod isn't eligible. -// There're several reasons: -// 1. The pod has a preemptionPolicy of Never. -// 2. The pod has already preempted other pods and the victims are in their graceful termination period. -// Currently we check the node that is nominated for this pod, and as long as there are -// terminating pods on this node, we don't attempt to preempt more pods. -func (pl *DefaultPreemption) PodEligibleToPreemptOthers(_ context.Context, pod *v1.Pod, nominatedNodeStatus *framework.Status) (bool, string) { - if pod.Spec.PreemptionPolicy != nil && *pod.Spec.PreemptionPolicy == v1.PreemptNever { - return false, "not eligible due to preemptionPolicy=Never." - } - - nodeInfos := pl.fh.SnapshotSharedLister().NodeInfos() - nomNodeName := pod.Status.NominatedNodeName - if len(nomNodeName) > 0 { - // If the pod's nominated node is considered as UnschedulableAndUnresolvable by the filters, - // then the pod should be considered for preempting again. - if nominatedNodeStatus.Code() == framework.UnschedulableAndUnresolvable { - return true, "" - } - - if nodeInfo, _ := nodeInfos.Get(nomNodeName); nodeInfo != nil { - podPriority := corev1helpers.PodPriority(pod) - for _, p := range nodeInfo.Pods { - if corev1helpers.PodPriority(p.Pod) < podPriority && podTerminatingByPreemption(p.Pod) { - // There is a terminating pod on the nominated node. - return false, "not eligible due to a terminating pod on the nominated node." - } - } - } - } - return true, "" -} - -// OrderedScoreFuncs returns a list of ordered score functions to select preferable node where victims will be preempted. -func (pl *DefaultPreemption) OrderedScoreFuncs(ctx context.Context, nodesToVictims map[string]*extenderv1.Victims) []func(node string) int64 { - return nil -} - -// podTerminatingByPreemption returns true if the pod is in the termination state caused by scheduler preemption. -func podTerminatingByPreemption(p *v1.Pod) bool { - if p.DeletionTimestamp == nil { - return false - } - - for _, condition := range p.Status.Conditions { - if condition.Type == v1.DisruptionTarget { - return condition.Status == v1.ConditionTrue && condition.Reason == v1.PodReasonPreemptionByScheduler - } - } - return false -} - -// filterPodsWithPDBViolation groups the given "pods" into two groups of "violatingPods" -// and "nonViolatingPods" based on whether their PDBs will be violated if they are -// preempted. -// This function is stable and does not change the order of received pods. So, if it -// receives a sorted list, grouping will preserve the order of the input list. -func filterPodsWithPDBViolation(podInfos []*framework.PodInfo, pdbs []*policy.PodDisruptionBudget) (violatingPodInfos, nonViolatingPodInfos []*framework.PodInfo) { - pdbsAllowed := make([]int32, len(pdbs)) - for i, pdb := range pdbs { - pdbsAllowed[i] = pdb.Status.DisruptionsAllowed - } - - for _, podInfo := range podInfos { - pod := podInfo.Pod - pdbForPodIsViolated := false - // A pod with no labels will not match any PDB. So, no need to check. - if len(pod.Labels) != 0 { - for i, pdb := range pdbs { - if pdb.Namespace != pod.Namespace { - continue - } - selector, err := metav1.LabelSelectorAsSelector(pdb.Spec.Selector) - if err != nil { - // This object has an invalid selector, it does not match the pod - continue - } - // A PDB with a nil or empty selector matches nothing. - if selector.Empty() || !selector.Matches(labels.Set(pod.Labels)) { - continue - } - - // Existing in DisruptedPods means it has been processed in API server, - // we don't treat it as a violating case. - if _, exist := pdb.Status.DisruptedPods[pod.Name]; exist { - continue - } - // Only decrement the matched pdb when it's not in its ; - // otherwise we may over-decrement the budget number. - pdbsAllowed[i]-- - // We have found a matching PDB. - if pdbsAllowed[i] < 0 { - pdbForPodIsViolated = true - } - } - } - if pdbForPodIsViolated { - violatingPodInfos = append(violatingPodInfos, podInfo) - } else { - nonViolatingPodInfos = append(nonViolatingPodInfos, podInfo) - } - } - return violatingPodInfos, nonViolatingPodInfos -} - -func getPDBLister(informerFactory informers.SharedInformerFactory) policylisters.PodDisruptionBudgetLister { - return informerFactory.Policy().V1().PodDisruptionBudgets().Lister() -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/OWNERS b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/OWNERS deleted file mode 100644 index 9dcfffa88..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/OWNERS +++ /dev/null @@ -1,9 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -reviewers: - - klueska - - pohly - - bart0sh -labels: - - sig/node - - wg/device-management diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go deleted file mode 100644 index 9c8d2305b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/allocateddevices.go +++ /dev/null @@ -1,175 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dynamicresources - -import ( - "sync" - - resourceapi "k8s.io/api/resource/v1beta1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/tools/cache" - "k8s.io/dynamic-resource-allocation/structured" - "k8s.io/klog/v2" - schedutil "k8s.io/kubernetes/pkg/scheduler/util" - "k8s.io/utils/ptr" -) - -// foreachAllocatedDevice invokes the provided callback for each -// device in the claim's allocation result which was allocated -// exclusively for the claim. -// -// Devices allocated with admin access can be shared with other -// claims and are skipped without invoking the callback. -// -// foreachAllocatedDevice does nothing if the claim is not allocated. -func foreachAllocatedDevice(claim *resourceapi.ResourceClaim, cb func(deviceID structured.DeviceID)) { - if claim.Status.Allocation == nil { - return - } - for _, result := range claim.Status.Allocation.Devices.Results { - // Kubernetes 1.31 did not set this, 1.32 always does. - // Supporting 1.31 is not worth the additional code that - // would have to be written (= looking up in request) because - // it is extremely unlikely that there really is a result - // that still exists in a cluster from 1.31 where this matters. - if ptr.Deref(result.AdminAccess, false) { - // Is not considered as allocated. - continue - } - deviceID := structured.MakeDeviceID(result.Driver, result.Pool, result.Device) - - // None of the users of this helper need to abort iterating, - // therefore it's not supported as it only would add overhead. - cb(deviceID) - } -} - -// allocatedDevices reacts to events in a cache and maintains a set of all allocated devices. -// This is cheaper than repeatedly calling List, making strings unique, and building the set -// each time PreFilter is called. -// -// All methods are thread-safe. Get returns a cloned set. -type allocatedDevices struct { - logger klog.Logger - - mutex sync.RWMutex - ids sets.Set[structured.DeviceID] -} - -func newAllocatedDevices(logger klog.Logger) *allocatedDevices { - return &allocatedDevices{ - logger: logger, - ids: sets.New[structured.DeviceID](), - } -} - -func (a *allocatedDevices) Get() sets.Set[structured.DeviceID] { - a.mutex.RLock() - defer a.mutex.RUnlock() - - return a.ids.Clone() -} - -func (a *allocatedDevices) handlers() cache.ResourceEventHandler { - return cache.ResourceEventHandlerFuncs{ - AddFunc: a.onAdd, - UpdateFunc: a.onUpdate, - DeleteFunc: a.onDelete, - } -} - -func (a *allocatedDevices) onAdd(obj any) { - claim, _, err := schedutil.As[*resourceapi.ResourceClaim](obj, nil) - if err != nil { - // Shouldn't happen. - a.logger.Error(err, "unexpected object in allocatedDevices.onAdd") - return - } - - if claim.Status.Allocation != nil { - a.addDevices(claim) - } -} - -func (a *allocatedDevices) onUpdate(oldObj, newObj any) { - originalClaim, modifiedClaim, err := schedutil.As[*resourceapi.ResourceClaim](oldObj, newObj) - if err != nil { - // Shouldn't happen. - a.logger.Error(err, "unexpected object in allocatedDevices.onUpdate") - return - } - - switch { - case originalClaim.Status.Allocation == nil && modifiedClaim.Status.Allocation != nil: - a.addDevices(modifiedClaim) - case originalClaim.Status.Allocation != nil && modifiedClaim.Status.Allocation == nil: - a.removeDevices(originalClaim) - default: - // Nothing to do. Either both nil or both non-nil, in which case the content - // also must be the same (immutable!). - } -} - -func (a *allocatedDevices) onDelete(obj any) { - claim, _, err := schedutil.As[*resourceapi.ResourceClaim](obj, nil) - if err != nil { - // Shouldn't happen. - a.logger.Error(err, "unexpected object in allocatedDevices.onDelete") - return - } - - a.removeDevices(claim) -} - -func (a *allocatedDevices) addDevices(claim *resourceapi.ResourceClaim) { - if claim.Status.Allocation == nil { - return - } - // Locking of the mutex gets minimized by pre-computing what needs to be done - // without holding the lock. - deviceIDs := make([]structured.DeviceID, 0, 20) - foreachAllocatedDevice(claim, func(deviceID structured.DeviceID) { - a.logger.V(6).Info("Observed device allocation", "device", deviceID, "claim", klog.KObj(claim)) - deviceIDs = append(deviceIDs, deviceID) - }) - - a.mutex.Lock() - defer a.mutex.Unlock() - for _, deviceID := range deviceIDs { - a.ids.Insert(deviceID) - } -} - -func (a *allocatedDevices) removeDevices(claim *resourceapi.ResourceClaim) { - if claim.Status.Allocation == nil { - return - } - - // Locking of the mutex gets minimized by pre-computing what needs to be done - // without holding the lock. - deviceIDs := make([]structured.DeviceID, 0, 20) - foreachAllocatedDevice(claim, func(deviceID structured.DeviceID) { - a.logger.V(6).Info("Observed device deallocation", "device", deviceID, "claim", klog.KObj(claim)) - deviceIDs = append(deviceIDs, deviceID) - }) - - a.mutex.Lock() - defer a.mutex.Unlock() - for _, deviceID := range deviceIDs { - a.ids.Delete(deviceID) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go deleted file mode 100644 index 47d3d5de4..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dra_manager.go +++ /dev/null @@ -1,228 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dynamicresources - -import ( - "context" - "fmt" - "sync" - - resourceapi "k8s.io/api/resource/v1beta1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/informers" - resourcelisters "k8s.io/client-go/listers/resource/v1beta1" - resourceslicetracker "k8s.io/dynamic-resource-allocation/resourceslice/tracker" - "k8s.io/dynamic-resource-allocation/structured" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/util/assumecache" -) - -var _ framework.SharedDRAManager = &DefaultDRAManager{} - -// DefaultDRAManager is the default implementation of SharedDRAManager. It obtains the DRA objects -// from API informers, and uses an AssumeCache and a map of in-flight allocations in order -// to avoid race conditions when modifying ResourceClaims. -type DefaultDRAManager struct { - resourceClaimTracker *claimTracker - resourceSliceLister *resourceSliceLister - deviceClassLister *deviceClassLister -} - -func NewDRAManager(ctx context.Context, claimsCache *assumecache.AssumeCache, resourceSliceTracker *resourceslicetracker.Tracker, informerFactory informers.SharedInformerFactory) *DefaultDRAManager { - logger := klog.FromContext(ctx) - - manager := &DefaultDRAManager{ - resourceClaimTracker: &claimTracker{ - cache: claimsCache, - inFlightAllocations: &sync.Map{}, - allocatedDevices: newAllocatedDevices(logger), - logger: logger, - }, - resourceSliceLister: &resourceSliceLister{tracker: resourceSliceTracker}, - deviceClassLister: &deviceClassLister{classLister: informerFactory.Resource().V1beta1().DeviceClasses().Lister()}, - } - - // Reacting to events is more efficient than iterating over the list - // repeatedly in PreFilter. - manager.resourceClaimTracker.cache.AddEventHandler(manager.resourceClaimTracker.allocatedDevices.handlers()) - - return manager -} - -func (s *DefaultDRAManager) ResourceClaims() framework.ResourceClaimTracker { - return s.resourceClaimTracker -} - -func (s *DefaultDRAManager) ResourceSlices() framework.ResourceSliceLister { - return s.resourceSliceLister -} - -func (s *DefaultDRAManager) DeviceClasses() framework.DeviceClassLister { - return s.deviceClassLister -} - -var _ framework.ResourceSliceLister = &resourceSliceLister{} - -type resourceSliceLister struct { - tracker *resourceslicetracker.Tracker -} - -func (l *resourceSliceLister) ListWithDeviceTaintRules() ([]*resourceapi.ResourceSlice, error) { - return l.tracker.ListPatchedResourceSlices() -} - -var _ framework.DeviceClassLister = &deviceClassLister{} - -type deviceClassLister struct { - classLister resourcelisters.DeviceClassLister -} - -func (l *deviceClassLister) Get(className string) (*resourceapi.DeviceClass, error) { - return l.classLister.Get(className) -} - -func (l *deviceClassLister) List() ([]*resourceapi.DeviceClass, error) { - return l.classLister.List(labels.Everything()) -} - -var _ framework.ResourceClaimTracker = &claimTracker{} - -type claimTracker struct { - // cache enables temporarily storing a newer claim object - // while the scheduler has allocated it and the corresponding object - // update from the apiserver has not been processed by the claim - // informer callbacks. ResourceClaimTracker get added here in PreBind and removed by - // the informer callback (based on the "newer than" comparison in the - // assume cache). - // - // It uses cache.MetaNamespaceKeyFunc to generate object names, which - // therefore are "/". - // - // This is necessary to ensure that reconstructing the resource usage - // at the start of a pod scheduling cycle doesn't reuse the resources - // assigned to such a claim. Alternatively, claim allocation state - // could also get tracked across pod scheduling cycles, but that - // - adds complexity (need to carefully sync state with informer events - // for claims and ResourceSlices) - // - would make integration with cluster autoscaler harder because it would need - // to trigger informer callbacks. - cache *assumecache.AssumeCache - // inFlightAllocations is a map from claim UUIDs to claim objects for those claims - // for which allocation was triggered during a scheduling cycle and the - // corresponding claim status update call in PreBind has not been done - // yet. If another pod needs the claim, the pod is treated as "not - // schedulable yet". The cluster event for the claim status update will - // make it schedulable. - // - // This mechanism avoids the following problem: - // - Pod A triggers allocation for claim X. - // - Pod B shares access to that claim and gets scheduled because - // the claim is assumed to be allocated. - // - PreBind for pod B is called first, tries to update reservedFor and - // fails because the claim is not really allocated yet. - // - // We could avoid the ordering problem by allowing either pod A or pod B - // to set the allocation. But that is more complicated and leads to another - // problem: - // - Pod A and B get scheduled as above. - // - PreBind for pod A gets called first, then fails with a temporary API error. - // It removes the updated claim from the assume cache because of that. - // - PreBind for pod B gets called next and succeeds with adding the - // allocation and its own reservedFor entry. - // - The assume cache is now not reflecting that the claim is allocated, - // which could lead to reusing the same resource for some other claim. - // - // A sync.Map is used because in practice sharing of a claim between - // pods is expected to be rare compared to per-pod claim, so we end up - // hitting the "multiple goroutines read, write, and overwrite entries - // for disjoint sets of keys" case that sync.Map is optimized for. - inFlightAllocations *sync.Map - allocatedDevices *allocatedDevices - logger klog.Logger -} - -func (c *claimTracker) ClaimHasPendingAllocation(claimUID types.UID) bool { - _, found := c.inFlightAllocations.Load(claimUID) - return found -} - -func (c *claimTracker) SignalClaimPendingAllocation(claimUID types.UID, allocatedClaim *resourceapi.ResourceClaim) error { - c.inFlightAllocations.Store(claimUID, allocatedClaim) - // There's no reason to return an error in this implementation, but the error is helpful for other implementations. - // For example, implementations that have to deal with fake claims might want to return an error if the allocation - // is for an invalid claim. - return nil -} - -func (c *claimTracker) RemoveClaimPendingAllocation(claimUID types.UID) (deleted bool) { - _, found := c.inFlightAllocations.LoadAndDelete(claimUID) - return found -} - -func (c *claimTracker) Get(namespace, claimName string) (*resourceapi.ResourceClaim, error) { - obj, err := c.cache.Get(namespace + "/" + claimName) - if err != nil { - return nil, err - } - claim, ok := obj.(*resourceapi.ResourceClaim) - if !ok { - return nil, fmt.Errorf("unexpected object type %T for assumed object %s/%s", obj, namespace, claimName) - } - return claim, nil -} - -func (c *claimTracker) List() ([]*resourceapi.ResourceClaim, error) { - var result []*resourceapi.ResourceClaim - // Probably not worth adding an index for? - objs := c.cache.List(nil) - for _, obj := range objs { - claim, ok := obj.(*resourceapi.ResourceClaim) - if ok { - result = append(result, claim) - } - } - return result, nil -} - -func (c *claimTracker) ListAllAllocatedDevices() (sets.Set[structured.DeviceID], error) { - // Start with a fresh set that matches the current known state of the - // world according to the informers. - allocated := c.allocatedDevices.Get() - - // Whatever is in flight also has to be checked. - c.inFlightAllocations.Range(func(key, value any) bool { - claim := value.(*resourceapi.ResourceClaim) - foreachAllocatedDevice(claim, func(deviceID structured.DeviceID) { - c.logger.V(6).Info("Device is in flight for allocation", "device", deviceID, "claim", klog.KObj(claim)) - allocated.Insert(deviceID) - }) - return true - }) - // There's no reason to return an error in this implementation, but the error might be helpful for other implementations. - return allocated, nil -} - -func (c *claimTracker) AssumeClaimAfterAPICall(claim *resourceapi.ResourceClaim) error { - return c.cache.Assume(claim) -} - -func (c *claimTracker) AssumedClaimRestore(namespace, claimName string) { - c.cache.Restore(namespace + "/" + claimName) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go deleted file mode 100644 index dd1adfc5a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources/dynamicresources.go +++ /dev/null @@ -1,910 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package dynamicresources - -import ( - "context" - "errors" - "fmt" - "slices" - "strings" - "sync" - - "github.com/google/go-cmp/cmp" //nolint:depguard - - v1 "k8s.io/api/core/v1" - resourceapi "k8s.io/api/resource/v1beta1" - apiequality "k8s.io/apimachinery/pkg/api/equality" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/util/retry" - "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" - "k8s.io/dynamic-resource-allocation/cel" - "k8s.io/dynamic-resource-allocation/resourceclaim" - "k8s.io/dynamic-resource-allocation/structured" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - schedutil "k8s.io/kubernetes/pkg/scheduler/util" -) - -const ( - // Name is the name of the plugin used in Registry and configurations. - Name = names.DynamicResources - - stateKey framework.StateKey = Name -) - -// The state is initialized in PreFilter phase. Because we save the pointer in -// framework.CycleState, in the later phases we don't need to call Write method -// to update the value -type stateData struct { - // A copy of all claims for the Pod (i.e. 1:1 match with - // pod.Spec.ResourceClaims), initially with the status from the start - // of the scheduling cycle. Each claim instance is read-only because it - // might come from the informer cache. The instances get replaced when - // the plugin itself successfully does an Update. - // - // Empty if the Pod has no claims. - claims []*resourceapi.ResourceClaim - - // Allocator handles claims with structured parameters. - allocator *structured.Allocator - - // mutex must be locked while accessing any of the fields below. - mutex sync.Mutex - - // The indices of all claims that: - // - are allocated - // - use delayed allocation or the builtin controller - // - were not available on at least one node - // - // Set in parallel during Filter, so write access there must be - // protected by the mutex. Used by PostFilter. - unavailableClaims sets.Set[int] - - informationsForClaim []informationForClaim - - // nodeAllocations caches the result of Filter for the nodes. - nodeAllocations map[string][]resourceapi.AllocationResult -} - -func (d *stateData) Clone() framework.StateData { - return d -} - -type informationForClaim struct { - // Node selector based on the claim status if allocated. - availableOnNodes *nodeaffinity.NodeSelector - - // Set by Reserved, published by PreBind. - allocation *resourceapi.AllocationResult -} - -// DynamicResources is a plugin that ensures that ResourceClaims are allocated. -type DynamicResources struct { - enabled bool - enableAdminAccess bool - enablePrioritizedList bool - enableSchedulingQueueHint bool - enablePartitionableDevices bool - enableDeviceTaints bool - - fh framework.Handle - clientset kubernetes.Interface - celCache *cel.Cache - draManager framework.SharedDRAManager -} - -// New initializes a new plugin and returns it. -func New(ctx context.Context, plArgs runtime.Object, fh framework.Handle, fts feature.Features) (framework.Plugin, error) { - if !fts.EnableDynamicResourceAllocation { - // Disabled, won't do anything. - return &DynamicResources{}, nil - } - - pl := &DynamicResources{ - enabled: true, - enableAdminAccess: fts.EnableDRAAdminAccess, - enableDeviceTaints: fts.EnableDRADeviceTaints, - enablePrioritizedList: fts.EnableDRAPrioritizedList, - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - enablePartitionableDevices: fts.EnablePartitionableDevices, - - fh: fh, - clientset: fh.ClientSet(), - // This is a LRU cache for compiled CEL expressions. The most - // recent 10 of them get reused across different scheduling - // cycles. - celCache: cel.NewCache(10), - draManager: fh.SharedDRAManager(), - } - - return pl, nil -} - -var _ framework.PreEnqueuePlugin = &DynamicResources{} -var _ framework.PreFilterPlugin = &DynamicResources{} -var _ framework.FilterPlugin = &DynamicResources{} -var _ framework.PostFilterPlugin = &DynamicResources{} -var _ framework.ReservePlugin = &DynamicResources{} -var _ framework.EnqueueExtensions = &DynamicResources{} -var _ framework.PreBindPlugin = &DynamicResources{} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *DynamicResources) Name() string { - return Name -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *DynamicResources) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - if !pl.enabled { - return nil, nil - } - // A resource might depend on node labels for topology filtering. - // A new or updated node may make pods schedulable. - // - // A note about UpdateNodeTaint event: - // Ideally, it's supposed to register only Add | UpdateNodeLabel because UpdateNodeTaint will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeLabel | framework.UpdateNodeTaint - if pl.enableSchedulingQueueHint { - // When QHint is enabled, the problematic preCheck is already removed, and we can remove UpdateNodeTaint. - nodeActionType = framework.Add | framework.UpdateNodeLabel - } - - events := []framework.ClusterEventWithHint{ - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}}, - // Allocation is tracked in ResourceClaims, so any changes may make the pods schedulable. - {Event: framework.ClusterEvent{Resource: framework.ResourceClaim, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterClaimChange}, - // Adding the ResourceClaim name to the pod status makes pods waiting for their ResourceClaim schedulable. - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.UpdatePodGeneratedResourceClaim}, QueueingHintFn: pl.isSchedulableAfterPodChange}, - // A pod might be waiting for a class to get created or modified. - {Event: framework.ClusterEvent{Resource: framework.DeviceClass, ActionType: framework.Add | framework.Update}}, - // Adding or updating a ResourceSlice might make a pod schedulable because new resources became available. - {Event: framework.ClusterEvent{Resource: framework.ResourceSlice, ActionType: framework.Add | framework.Update}}, - } - - return events, nil -} - -// PreEnqueue checks if there are known reasons why a pod currently cannot be -// scheduled. When this fails, one of the registered events can trigger another -// attempt. -func (pl *DynamicResources) PreEnqueue(ctx context.Context, pod *v1.Pod) (status *framework.Status) { - if !pl.enabled { - return nil - } - - if err := pl.foreachPodResourceClaim(pod, nil); err != nil { - return statusUnschedulable(klog.FromContext(ctx), err.Error()) - } - return nil -} - -// isSchedulableAfterClaimChange is invoked for add and update claim events reported by -// an informer. It checks whether that change made a previously unschedulable -// pod schedulable. It errs on the side of letting a pod scheduling attempt -// happen. The delete claim event will not invoke it, so newObj will never be nil. -func (pl *DynamicResources) isSchedulableAfterClaimChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalClaim, modifiedClaim, err := schedutil.As[*resourceapi.ResourceClaim](oldObj, newObj) - if err != nil { - // Shouldn't happen. - return framework.Queue, fmt.Errorf("unexpected object in isSchedulableAfterClaimChange: %w", err) - } - - usesClaim := false - if err := pl.foreachPodResourceClaim(pod, func(_ string, claim *resourceapi.ResourceClaim) { - if claim.UID == modifiedClaim.UID { - usesClaim = true - } - }); err != nil { - // This is not an unexpected error: we know that - // foreachPodResourceClaim only returns errors for "not - // schedulable". - if loggerV := logger.V(6); loggerV.Enabled() { - owner := metav1.GetControllerOf(modifiedClaim) - loggerV.Info("pod is not schedulable after resource claim change", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim), "claimOwner", owner, "reason", err.Error()) - } - return framework.QueueSkip, nil - } - - if originalClaim != nil && - originalClaim.Status.Allocation != nil && - modifiedClaim.Status.Allocation == nil { - // A claim with structured parameters was deallocated. This might have made - // resources available for other pods. - logger.V(6).Info("claim with structured parameters got deallocated", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim)) - return framework.Queue, nil - } - - if !usesClaim { - // This was not the claim the pod was waiting for. - logger.V(6).Info("unrelated claim got modified", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim)) - return framework.QueueSkip, nil - } - - if originalClaim == nil { - logger.V(5).Info("claim for pod got created", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim)) - return framework.Queue, nil - } - - // Modifications may or may not be relevant. If the entire - // status is as before, then something else must have changed - // and we don't care. What happens in practice is that the - // resource driver adds the finalizer. - if apiequality.Semantic.DeepEqual(&originalClaim.Status, &modifiedClaim.Status) { - if loggerV := logger.V(7); loggerV.Enabled() { - // Log more information. - loggerV.Info("claim for pod got modified where the pod doesn't care", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim), "diff", cmp.Diff(originalClaim, modifiedClaim)) - } else { - logger.V(6).Info("claim for pod got modified where the pod doesn't care", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim)) - } - return framework.QueueSkip, nil - } - - logger.V(5).Info("status of claim for pod got updated", "pod", klog.KObj(pod), "claim", klog.KObj(modifiedClaim)) - return framework.Queue, nil -} - -// isSchedulableAfterPodChange is invoked for update pod events reported by -// an informer. It checks whether that change adds the ResourceClaim(s) that the -// pod has been waiting for. -func (pl *DynamicResources) isSchedulableAfterPodChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, modifiedPod, err := schedutil.As[*v1.Pod](nil, newObj) - if err != nil { - // Shouldn't happen. - return framework.Queue, fmt.Errorf("unexpected object in isSchedulableAfterClaimChange: %w", err) - } - - if pod.UID != modifiedPod.UID { - logger.V(7).Info("pod is not schedulable after change in other pod", "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - if err := pl.foreachPodResourceClaim(modifiedPod, nil); err != nil { - // This is not an unexpected error: we know that - // foreachPodResourceClaim only returns errors for "not - // schedulable". - logger.V(6).Info("pod is not schedulable after being updated", "pod", klog.KObj(pod)) - return framework.QueueSkip, nil - } - - logger.V(5).Info("pod got updated and is schedulable", "pod", klog.KObj(pod)) - return framework.Queue, nil -} - -// podResourceClaims returns the ResourceClaims for all pod.Spec.PodResourceClaims. -func (pl *DynamicResources) podResourceClaims(pod *v1.Pod) ([]*resourceapi.ResourceClaim, error) { - claims := make([]*resourceapi.ResourceClaim, 0, len(pod.Spec.ResourceClaims)) - if err := pl.foreachPodResourceClaim(pod, func(_ string, claim *resourceapi.ResourceClaim) { - // We store the pointer as returned by the lister. The - // assumption is that if a claim gets modified while our code - // runs, the cache will store a new pointer, not mutate the - // existing object that we point to here. - claims = append(claims, claim) - }); err != nil { - return nil, err - } - return claims, nil -} - -// foreachPodResourceClaim checks that each ResourceClaim for the pod exists. -// It calls an optional handler for those claims that it finds. -func (pl *DynamicResources) foreachPodResourceClaim(pod *v1.Pod, cb func(podResourceName string, claim *resourceapi.ResourceClaim)) error { - for _, resource := range pod.Spec.ResourceClaims { - claimName, mustCheckOwner, err := resourceclaim.Name(pod, &resource) - if err != nil { - return err - } - // The claim name might be nil if no underlying resource claim - // was generated for the referenced claim. There are valid use - // cases when this might happen, so we simply skip it. - if claimName == nil { - continue - } - claim, err := pl.draManager.ResourceClaims().Get(pod.Namespace, *claimName) - if err != nil { - return err - } - - if claim.DeletionTimestamp != nil { - return fmt.Errorf("resourceclaim %q is being deleted", claim.Name) - } - - if mustCheckOwner { - if err := resourceclaim.IsForPod(pod, claim); err != nil { - return err - } - } - if cb != nil { - cb(resource.Name, claim) - } - } - return nil -} - -// PreFilter invoked at the prefilter extension point to check if pod has all -// immediate claims bound. UnschedulableAndUnresolvable is returned if -// the pod cannot be scheduled at the moment on any node. -func (pl *DynamicResources) PreFilter(ctx context.Context, state *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - if !pl.enabled { - return nil, framework.NewStatus(framework.Skip) - } - logger := klog.FromContext(ctx) - - // If the pod does not reference any claim, we don't need to do - // anything for it. We just initialize an empty state to record that - // observation for the other functions. This gets updated below - // if we get that far. - s := &stateData{} - state.Write(stateKey, s) - - claims, err := pl.podResourceClaims(pod) - if err != nil { - return nil, statusUnschedulable(logger, err.Error()) - } - logger.V(5).Info("pod resource claims", "pod", klog.KObj(pod), "resourceclaims", klog.KObjSlice(claims)) - - // If the pod does not reference any claim, - // DynamicResources Filter has nothing to do with the Pod. - if len(claims) == 0 { - return nil, framework.NewStatus(framework.Skip) - } - - // All claims which the scheduler needs to allocate itself. - allocateClaims := make([]*resourceapi.ResourceClaim, 0, len(claims)) - - s.informationsForClaim = make([]informationForClaim, len(claims)) - for index, claim := range claims { - if claim.Status.Allocation != nil && - !resourceclaim.CanBeReserved(claim) && - !resourceclaim.IsReservedForPod(pod, claim) { - // Resource is in use. The pod has to wait. - return nil, statusUnschedulable(logger, "resourceclaim in use", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) - } - - if claim.Status.Allocation != nil { - if claim.Status.Allocation.NodeSelector != nil { - nodeSelector, err := nodeaffinity.NewNodeSelector(claim.Status.Allocation.NodeSelector) - if err != nil { - return nil, statusError(logger, err) - } - s.informationsForClaim[index].availableOnNodes = nodeSelector - } - } else { - allocateClaims = append(allocateClaims, claim) - - // Allocation in flight? Better wait for that - // to finish, see inFlightAllocations - // documentation for details. - if pl.draManager.ResourceClaims().ClaimHasPendingAllocation(claim.UID) { - return nil, statusUnschedulable(logger, fmt.Sprintf("resource claim %s is in the process of being allocated", klog.KObj(claim))) - } - - // Check all requests and device classes. If a class - // does not exist, scheduling cannot proceed, no matter - // how the claim is being allocated. - // - // When using a control plane controller, a class might - // have a node filter. This is useful for trimming the - // initial set of potential nodes before we ask the - // driver(s) for information about the specific pod. - for _, request := range claim.Spec.Devices.Requests { - // The requirements differ depending on whether the request has a list of - // alternative subrequests defined in the firstAvailable field. - if len(request.FirstAvailable) == 0 { - if status := pl.validateDeviceClass(logger, request.DeviceClassName, request.Name); status != nil { - return nil, status - } - } else { - if !pl.enablePrioritizedList { - return nil, statusUnschedulable(logger, fmt.Sprintf("resource claim %s, request %s: has subrequests, but the DRAPrioritizedList feature is disabled", klog.KObj(claim), request.Name)) - } - for _, subRequest := range request.FirstAvailable { - qualRequestName := strings.Join([]string{request.Name, subRequest.Name}, "/") - if status := pl.validateDeviceClass(logger, subRequest.DeviceClassName, qualRequestName); status != nil { - return nil, status - } - } - } - } - } - } - - if len(allocateClaims) > 0 { - logger.V(5).Info("Preparing allocation with structured parameters", "pod", klog.KObj(pod), "resourceclaims", klog.KObjSlice(allocateClaims)) - - // Doing this over and over again for each pod could be avoided - // by setting the allocator up once and then keeping it up-to-date - // as changes are observed. - // - // But that would cause problems for using the plugin in the - // Cluster Autoscaler. If this step here turns out to be - // expensive, we may have to maintain and update state more - // persistently. - // - // Claims (and thus their devices) are treated as "allocated" if they are in the assume cache - // or currently their allocation is in-flight. This does not change - // during filtering, so we can determine that once. - allAllocatedDevices, err := pl.draManager.ResourceClaims().ListAllAllocatedDevices() - if err != nil { - return nil, statusError(logger, err) - } - slices, err := pl.draManager.ResourceSlices().ListWithDeviceTaintRules() - if err != nil { - return nil, statusError(logger, err) - } - features := structured.Features{ - AdminAccess: pl.enableAdminAccess, - PrioritizedList: pl.enablePrioritizedList, - PartitionableDevices: pl.enablePartitionableDevices, - DeviceTaints: pl.enableDeviceTaints, - } - allocator, err := structured.NewAllocator(ctx, features, allocateClaims, allAllocatedDevices, pl.draManager.DeviceClasses(), slices, pl.celCache) - if err != nil { - return nil, statusError(logger, err) - } - s.allocator = allocator - s.nodeAllocations = make(map[string][]resourceapi.AllocationResult) - } - - s.claims = claims - return nil, nil -} - -func (pl *DynamicResources) validateDeviceClass(logger klog.Logger, deviceClassName, requestName string) *framework.Status { - if deviceClassName == "" { - return statusError(logger, fmt.Errorf("request %s: unsupported request type", requestName)) - } - - _, err := pl.draManager.DeviceClasses().Get(deviceClassName) - if err != nil { - // If the class cannot be retrieved, allocation cannot proceed. - if apierrors.IsNotFound(err) { - // Here we mark the pod as "unschedulable", so it'll sleep in - // the unscheduleable queue until a DeviceClass event occurs. - return statusUnschedulable(logger, fmt.Sprintf("request %s: device class %s does not exist", requestName, deviceClassName)) - } - } - return nil -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (pl *DynamicResources) PreFilterExtensions() framework.PreFilterExtensions { - return nil -} - -func getStateData(cs *framework.CycleState) (*stateData, error) { - state, err := cs.Read(stateKey) - if err != nil { - return nil, err - } - s, ok := state.(*stateData) - if !ok { - return nil, errors.New("unable to convert state into stateData") - } - return s, nil -} - -// Filter invoked at the filter extension point. -// It evaluates if a pod can fit due to the resources it requests, -// for both allocated and unallocated claims. -// -// For claims that are bound, then it checks that the node affinity is -// satisfied by the given node. -// -// For claims that are unbound, it checks whether the claim might get allocated -// for the node. -func (pl *DynamicResources) Filter(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - if !pl.enabled { - return nil - } - state, err := getStateData(cs) - if err != nil { - return statusError(klog.FromContext(ctx), err) - } - if len(state.claims) == 0 { - return nil - } - - logger := klog.FromContext(ctx) - node := nodeInfo.Node() - - var unavailableClaims []int - for index, claim := range state.claims { - logger.V(10).Info("filtering based on resource claims of the pod", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim)) - - // This node selector only gets set if the claim is allocated. - if nodeSelector := state.informationsForClaim[index].availableOnNodes; nodeSelector != nil && !nodeSelector.Match(node) { - logger.V(5).Info("allocation's node selector does not match", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaim", klog.KObj(claim)) - unavailableClaims = append(unavailableClaims, index) - } - } - - // Use allocator to check the node and cache the result in case that the node is picked. - var allocations []resourceapi.AllocationResult - if state.allocator != nil { - allocCtx := ctx - if loggerV := logger.V(5); loggerV.Enabled() { - allocCtx = klog.NewContext(allocCtx, klog.LoggerWithValues(logger, "node", klog.KObj(node))) - } - - a, err := state.allocator.Allocate(allocCtx, node) - if err != nil { - // This should only fail if there is something wrong with the claim or class. - // Return an error to abort scheduling of it. - // - // This will cause retries. It would be slightly nicer to mark it as unschedulable - // *and* abort scheduling. Then only cluster event for updating the claim or class - // with the broken CEL expression would trigger rescheduling. - // - // But we cannot do both. As this shouldn't occur often, aborting like this is - // better than the more complicated alternative (return Unschedulable here, remember - // the error, then later raise it again later if needed). - return statusError(logger, err, "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaims", klog.KObjSlice(state.allocator.ClaimsToAllocate())) - } - // Check for exact length just to be sure. In practice this is all-or-nothing. - if len(a) != len(state.allocator.ClaimsToAllocate()) { - return statusUnschedulable(logger, "cannot allocate all claims", "pod", klog.KObj(pod), "node", klog.KObj(node), "resourceclaims", klog.KObjSlice(state.allocator.ClaimsToAllocate())) - } - // Reserve uses this information. - allocations = a - } - - // Store information in state while holding the mutex. - if state.allocator != nil || len(unavailableClaims) > 0 { - state.mutex.Lock() - defer state.mutex.Unlock() - } - - if len(unavailableClaims) > 0 { - // Remember all unavailable claims. This might be observed - // concurrently, so we have to lock the state before writing. - - if state.unavailableClaims == nil { - state.unavailableClaims = sets.New[int]() - } - - for _, index := range unavailableClaims { - state.unavailableClaims.Insert(index) - } - return statusUnschedulable(logger, "resourceclaim not available on the node", "pod", klog.KObj(pod)) - } - - if state.allocator != nil { - state.nodeAllocations[node.Name] = allocations - } - - return nil -} - -// PostFilter checks whether there are allocated claims that could get -// deallocated to help get the Pod schedulable. If yes, it picks one and -// requests its deallocation. This only gets called when filtering found no -// suitable node. -func (pl *DynamicResources) PostFilter(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, filteredNodeStatusMap framework.NodeToStatusReader) (*framework.PostFilterResult, *framework.Status) { - if !pl.enabled { - return nil, framework.NewStatus(framework.Unschedulable, "plugin disabled") - } - // If a Pod doesn't have any resource claims attached to it, there is no need for further processing. - // Thus we provide a fast path for this case to avoid unnecessary computations. - if len(pod.Spec.ResourceClaims) == 0 { - return nil, framework.NewStatus(framework.Unschedulable) - } - logger := klog.FromContext(ctx) - state, err := getStateData(cs) - if err != nil { - return nil, statusError(logger, err) - } - if len(state.claims) == 0 { - return nil, framework.NewStatus(framework.Unschedulable, "no new claims to deallocate") - } - - // Iterating over a map is random. This is intentional here, we want to - // pick one claim randomly because there is no better heuristic. - for index := range state.unavailableClaims { - claim := state.claims[index] - if len(claim.Status.ReservedFor) == 0 || - len(claim.Status.ReservedFor) == 1 && claim.Status.ReservedFor[0].UID == pod.UID { - claim := claim.DeepCopy() - claim.Status.ReservedFor = nil - claim.Status.Allocation = nil - logger.V(5).Info("Deallocation of ResourceClaim", "pod", klog.KObj(pod), "resourceclaim", klog.KObj(claim)) - if _, err := pl.clientset.ResourceV1beta1().ResourceClaims(claim.Namespace).UpdateStatus(ctx, claim, metav1.UpdateOptions{}); err != nil { - return nil, statusError(logger, err) - } - return nil, framework.NewStatus(framework.Unschedulable, "deallocation of ResourceClaim completed") - } - } - return nil, framework.NewStatus(framework.Unschedulable, "still not schedulable") -} - -// Reserve reserves claims for the pod. -func (pl *DynamicResources) Reserve(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) (status *framework.Status) { - if !pl.enabled { - return nil - } - state, err := getStateData(cs) - if err != nil { - return statusError(klog.FromContext(ctx), err) - } - if len(state.claims) == 0 { - return nil - } - - logger := klog.FromContext(ctx) - - numClaimsWithAllocator := 0 - for _, claim := range state.claims { - if claim.Status.Allocation != nil { - // Allocated, but perhaps not reserved yet. We checked in PreFilter that - // the pod could reserve the claim. Instead of reserving here by - // updating the ResourceClaim status, we assume that reserving - // will work and only do it for real during binding. If it fails at - // that time, some other pod was faster and we have to try again. - continue - } - - numClaimsWithAllocator++ - } - - if numClaimsWithAllocator == 0 { - // Nothing left to do. - return nil - } - - // Prepare allocation of claims handled by the schedulder. - if state.allocator != nil { - // Entries in these two slices match each other. - claimsToAllocate := state.allocator.ClaimsToAllocate() - allocations, ok := state.nodeAllocations[nodeName] - if !ok { - // We checked before that the node is suitable. This shouldn't have failed, - // so treat this as an error. - return statusError(logger, errors.New("claim allocation not found for node")) - } - - // Sanity check: do we have results for all pending claims? - if len(allocations) != len(claimsToAllocate) || - len(allocations) != numClaimsWithAllocator { - return statusError(logger, fmt.Errorf("internal error, have %d allocations, %d claims to allocate, want %d claims", len(allocations), len(claimsToAllocate), numClaimsWithAllocator)) - } - - for i, claim := range claimsToAllocate { - index := slices.Index(state.claims, claim) - if index < 0 { - return statusError(logger, fmt.Errorf("internal error, claim %s with allocation not found", claim.Name)) - } - allocation := &allocations[i] - state.informationsForClaim[index].allocation = allocation - - // Strictly speaking, we don't need to store the full modified object. - // The allocation would be enough. The full object is useful for - // debugging, testing and the allocator, so let's make it realistic. - claim = claim.DeepCopy() - if !slices.Contains(claim.Finalizers, resourceapi.Finalizer) { - claim.Finalizers = append(claim.Finalizers, resourceapi.Finalizer) - } - claim.Status.Allocation = allocation - err := pl.draManager.ResourceClaims().SignalClaimPendingAllocation(claim.UID, claim) - if err != nil { - return statusError(logger, fmt.Errorf("internal error, couldn't signal allocation for claim %s", claim.Name)) - } - logger.V(5).Info("Reserved resource in allocation result", "claim", klog.KObj(claim), "allocation", klog.Format(allocation)) - } - } - - return nil -} - -// Unreserve clears the ReservedFor field for all claims. -// It's idempotent, and does nothing if no state found for the given pod. -func (pl *DynamicResources) Unreserve(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) { - if !pl.enabled { - return - } - state, err := getStateData(cs) - if err != nil { - return - } - if len(state.claims) == 0 { - return - } - - logger := klog.FromContext(ctx) - - for index, claim := range state.claims { - // If allocation was in-flight, then it's not anymore and we need to revert the - // claim object in the assume cache to what it was before. - if deleted := pl.draManager.ResourceClaims().RemoveClaimPendingAllocation(state.claims[index].UID); deleted { - pl.draManager.ResourceClaims().AssumedClaimRestore(claim.Namespace, claim.Name) - } - - if claim.Status.Allocation != nil && - resourceclaim.IsReservedForPod(pod, claim) { - // Remove pod from ReservedFor. A strategic-merge-patch is used - // because that allows removing an individual entry without having - // the latest slice. - patch := fmt.Sprintf(`{"metadata": {"uid": %q}, "status": { "reservedFor": [ {"$patch": "delete", "uid": %q} ] }}`, - claim.UID, - pod.UID, - ) - logger.V(5).Info("unreserve", "resourceclaim", klog.KObj(claim), "pod", klog.KObj(pod)) - claim, err := pl.clientset.ResourceV1beta1().ResourceClaims(claim.Namespace).Patch(ctx, claim.Name, types.StrategicMergePatchType, []byte(patch), metav1.PatchOptions{}, "status") - if err != nil { - // We will get here again when pod scheduling is retried. - logger.Error(err, "unreserve", "resourceclaim", klog.KObj(claim)) - } - } - } -} - -// PreBind gets called in a separate goroutine after it has been determined -// that the pod should get bound to this node. Because Reserve did not actually -// reserve claims, we need to do it now. For claims with the builtin controller, -// we also handle the allocation. -// -// If anything fails, we return an error and -// the pod will have to go into the backoff queue. The scheduler will call -// Unreserve as part of the error handling. -func (pl *DynamicResources) PreBind(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { - if !pl.enabled { - return nil - } - state, err := getStateData(cs) - if err != nil { - return statusError(klog.FromContext(ctx), err) - } - if len(state.claims) == 0 { - return nil - } - - logger := klog.FromContext(ctx) - - for index, claim := range state.claims { - if !resourceclaim.IsReservedForPod(pod, claim) { - claim, err := pl.bindClaim(ctx, state, index, pod, nodeName) - if err != nil { - return statusError(logger, err) - } - state.claims[index] = claim - } - } - // If we get here, we know that reserving the claim for - // the pod worked and we can proceed with binding it. - return nil -} - -// bindClaim gets called by PreBind for claim which is not reserved for the pod yet. -// It might not even be allocated. bindClaim then ensures that the allocation -// and reservation are recorded. This finishes the work started in Reserve. -func (pl *DynamicResources) bindClaim(ctx context.Context, state *stateData, index int, pod *v1.Pod, nodeName string) (patchedClaim *resourceapi.ResourceClaim, finalErr error) { - logger := klog.FromContext(ctx) - claim := state.claims[index].DeepCopy() - allocation := state.informationsForClaim[index].allocation - defer func() { - if allocation != nil { - // The scheduler was handling allocation. Now that has - // completed, either successfully or with a failure. - if finalErr == nil { - // This can fail, but only for reasons that are okay (concurrent delete or update). - // Shouldn't happen in this case. - if err := pl.draManager.ResourceClaims().AssumeClaimAfterAPICall(claim); err != nil { - logger.V(5).Info("Claim not stored in assume cache", "err", finalErr) - } - } - pl.draManager.ResourceClaims().RemoveClaimPendingAllocation(claim.UID) - } - }() - - logger.V(5).Info("preparing claim status update", "claim", klog.KObj(state.claims[index]), "allocation", klog.Format(allocation)) - - // We may run into a ResourceVersion conflict because there may be some - // benign concurrent changes. In that case we get the latest claim and - // try again. - refreshClaim := false - retryErr := retry.RetryOnConflict(retry.DefaultRetry, func() error { - if refreshClaim { - updatedClaim, err := pl.clientset.ResourceV1beta1().ResourceClaims(claim.Namespace).Get(ctx, claim.Name, metav1.GetOptions{}) - if err != nil { - return fmt.Errorf("get updated claim %s after conflict: %w", klog.KObj(claim), err) - } - logger.V(5).Info("retrying update after conflict", "claim", klog.KObj(claim)) - claim = updatedClaim - } else { - // All future retries must get a new claim first. - refreshClaim = true - } - - if claim.DeletionTimestamp != nil { - return fmt.Errorf("claim %s got deleted in the meantime", klog.KObj(claim)) - } - - // Do we need to store an allocation result from Reserve? - if allocation != nil { - if claim.Status.Allocation != nil { - return fmt.Errorf("claim %s got allocated elsewhere in the meantime", klog.KObj(claim)) - } - - // The finalizer needs to be added in a normal update. - // If we were interrupted in the past, it might already be set and we simply continue. - if !slices.Contains(claim.Finalizers, resourceapi.Finalizer) { - claim.Finalizers = append(claim.Finalizers, resourceapi.Finalizer) - updatedClaim, err := pl.clientset.ResourceV1beta1().ResourceClaims(claim.Namespace).Update(ctx, claim, metav1.UpdateOptions{}) - if err != nil { - return fmt.Errorf("add finalizer to claim %s: %w", klog.KObj(claim), err) - } - claim = updatedClaim - } - claim.Status.Allocation = allocation - } - - // We can simply try to add the pod here without checking - // preconditions. The apiserver will tell us with a - // non-conflict error if this isn't possible. - claim.Status.ReservedFor = append(claim.Status.ReservedFor, resourceapi.ResourceClaimConsumerReference{Resource: "pods", Name: pod.Name, UID: pod.UID}) - updatedClaim, err := pl.clientset.ResourceV1beta1().ResourceClaims(claim.Namespace).UpdateStatus(ctx, claim, metav1.UpdateOptions{}) - if err != nil { - if allocation != nil { - return fmt.Errorf("add allocation and reservation to claim %s: %w", klog.KObj(claim), err) - } - return fmt.Errorf("add reservation to claim %s: %w", klog.KObj(claim), err) - } - claim = updatedClaim - return nil - }) - - if retryErr != nil { - return nil, retryErr - } - - logger.V(5).Info("reserved", "pod", klog.KObj(pod), "node", klog.ObjectRef{Name: nodeName}, "resourceclaim", klog.Format(claim)) - return claim, nil -} - -// statusUnschedulable ensures that there is a log message associated with the -// line where the status originated. -func statusUnschedulable(logger klog.Logger, reason string, kv ...interface{}) *framework.Status { - if loggerV := logger.V(5); loggerV.Enabled() { - helper, loggerV := loggerV.WithCallStackHelper() - helper() - kv = append(kv, "reason", reason) - // nolint: logcheck // warns because it cannot check key/values - loggerV.Info("pod unschedulable", kv...) - } - return framework.NewStatus(framework.UnschedulableAndUnresolvable, reason) -} - -// statusError ensures that there is a log message associated with the -// line where the error originated. -func statusError(logger klog.Logger, err error, kv ...interface{}) *framework.Status { - if loggerV := logger.V(5); loggerV.Enabled() { - helper, loggerV := loggerV.WithCallStackHelper() - helper() - // nolint: logcheck // warns because it cannot check key/values - loggerV.Error(err, "dynamic resource plugin failed", kv...) - } - return framework.AsStatus(err) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go deleted file mode 100644 index 7e7f1a1b8..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature/feature.go +++ /dev/null @@ -1,38 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package feature - -// Features carries feature gate values used by various plugins. -// This struct allows us to break the dependency of the plugins on -// the internal k8s features pkg. -type Features struct { - EnableDRAPrioritizedList bool - EnableDRAAdminAccess bool - EnableDRADeviceTaints bool - EnableDynamicResourceAllocation bool - EnableVolumeAttributesClass bool - EnableCSIMigrationPortworx bool - EnableNodeInclusionPolicyInPodTopologySpread bool - EnableMatchLabelKeysInPodTopologySpread bool - EnableInPlacePodVerticalScaling bool - EnableSidecarContainers bool - EnableSchedulingQueueHint bool - EnableAsyncPreemption bool - EnablePodLevelResources bool - EnablePartitionableDevices bool - EnableStorageCapacityScoring bool -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/normalize_score.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/normalize_score.go deleted file mode 100644 index 3d35ca304..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/normalize_score.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package helper - -import ( - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// DefaultNormalizeScore generates a Normalize Score function that can normalize the -// scores from [0, max(scores)] to [0, maxPriority]. If reverse is set to true, it -// reverses the scores by subtracting it from maxPriority. -// Note: The input scores are always assumed to be non-negative integers. -func DefaultNormalizeScore(maxPriority int64, reverse bool, scores framework.NodeScoreList) *framework.Status { - var maxCount int64 - for i := range scores { - if scores[i].Score > maxCount { - maxCount = scores[i].Score - } - } - - if maxCount == 0 { - if reverse { - for i := range scores { - scores[i].Score = maxPriority - } - } - return nil - } - - for i := range scores { - score := scores[i].Score - - score = maxPriority * score / maxCount - if reverse { - score = maxPriority - score - } - - scores[i].Score = score - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/shape_score.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/shape_score.go deleted file mode 100644 index f12488b14..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/shape_score.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package helper - -// FunctionShape represents a collection of FunctionShapePoint. -type FunctionShape []FunctionShapePoint - -// FunctionShapePoint represents a shape point. -type FunctionShapePoint struct { - // Utilization is function argument. - Utilization int64 - // Score is function value. - Score int64 -} - -// BuildBrokenLinearFunction creates a function which is built using linear segments. Segments are defined via shape array. -// Shape[i].Utilization slice represents points on "Utilization" axis where different segments meet. -// Shape[i].Score represents function values at meeting points. -// -// function f(p) is defined as: -// -// shape[0].Score for p < shape[0].Utilization -// shape[n-1].Score for p > shape[n-1].Utilization -// -// and linear between points (p < shape[i].Utilization) -func BuildBrokenLinearFunction(shape FunctionShape) func(int64) int64 { - return func(p int64) int64 { - for i := 0; i < len(shape); i++ { - if p <= int64(shape[i].Utilization) { - if i == 0 { - return shape[0].Score - } - return shape[i-1].Score + (shape[i].Score-shape[i-1].Score)*(p-shape[i-1].Utilization)/(shape[i].Utilization-shape[i-1].Utilization) - } - } - return shape[len(shape)-1].Score - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/spread.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/spread.go deleted file mode 100644 index 636bcaee4..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/spread.go +++ /dev/null @@ -1,116 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package helper - -import ( - appsv1 "k8s.io/api/apps/v1" - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime/schema" - appslisters "k8s.io/client-go/listers/apps/v1" - corelisters "k8s.io/client-go/listers/core/v1" -) - -var ( - rcKind = v1.SchemeGroupVersion.WithKind("ReplicationController") - rsKind = appsv1.SchemeGroupVersion.WithKind("ReplicaSet") - ssKind = appsv1.SchemeGroupVersion.WithKind("StatefulSet") -) - -// DefaultSelector returns a selector deduced from the Services, Replication -// Controllers, Replica Sets, and Stateful Sets matching the given pod. -func DefaultSelector( - pod *v1.Pod, - sl corelisters.ServiceLister, - cl corelisters.ReplicationControllerLister, - rsl appslisters.ReplicaSetLister, - ssl appslisters.StatefulSetLister, -) labels.Selector { - labelSet := make(labels.Set) - // Since services, RCs, RSs and SSs match the pod, they won't have conflicting - // labels. Merging is safe. - - if services, err := GetPodServices(sl, pod); err == nil { - for _, service := range services { - labelSet = labels.Merge(labelSet, service.Spec.Selector) - } - } - selector := labelSet.AsSelector() - - owner := metav1.GetControllerOfNoCopy(pod) - if owner == nil { - return selector - } - - gv, err := schema.ParseGroupVersion(owner.APIVersion) - if err != nil { - return selector - } - - gvk := gv.WithKind(owner.Kind) - switch gvk { - case rcKind: - if rc, err := cl.ReplicationControllers(pod.Namespace).Get(owner.Name); err == nil { - labelSet = labels.Merge(labelSet, rc.Spec.Selector) - selector = labelSet.AsSelector() - } - case rsKind: - if rs, err := rsl.ReplicaSets(pod.Namespace).Get(owner.Name); err == nil { - if other, err := metav1.LabelSelectorAsSelector(rs.Spec.Selector); err == nil { - if r, ok := other.Requirements(); ok { - selector = selector.Add(r...) - } - } - } - case ssKind: - if ss, err := ssl.StatefulSets(pod.Namespace).Get(owner.Name); err == nil { - if other, err := metav1.LabelSelectorAsSelector(ss.Spec.Selector); err == nil { - if r, ok := other.Requirements(); ok { - selector = selector.Add(r...) - } - } - } - default: - // Not owned by a supported controller. - } - - return selector -} - -// GetPodServices gets the services that have the selector that match the labels on the given pod. -func GetPodServices(sl corelisters.ServiceLister, pod *v1.Pod) ([]*v1.Service, error) { - allServices, err := sl.Services(pod.Namespace).List(labels.Everything()) - if err != nil { - return nil, err - } - - var services []*v1.Service - for i := range allServices { - service := allServices[i] - if service.Spec.Selector == nil { - // services with nil selectors match nothing, not everything. - continue - } - selector := labels.Set(service.Spec.Selector).AsSelectorPreValidated() - if selector.Matches(labels.Set(pod.Labels)) { - services = append(services, service) - } - } - - return services, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/taint.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/taint.go deleted file mode 100644 index 7502d9ce4..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper/taint.go +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package helper - -import v1 "k8s.io/api/core/v1" - -// DoNotScheduleTaintsFilterFunc returns the filter function that can -// filter out the node taints that reject scheduling Pod on a Node. -func DoNotScheduleTaintsFilterFunc() func(t *v1.Taint) bool { - return func(t *v1.Taint) bool { - // PodToleratesNodeTaints is only interested in NoSchedule and NoExecute taints. - return t.Effect == v1.TaintEffectNoSchedule || t.Effect == v1.TaintEffectNoExecute - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go deleted file mode 100644 index 694d457c7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality/image_locality.go +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package imagelocality - -import ( - "context" - "strings" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" -) - -// The two thresholds are used as bounds for the image score range. They correspond to a reasonable size range for -// container images compressed and stored in registries; 90%ile of images on dockerhub drops into this range. -const ( - mb int64 = 1024 * 1024 - minThreshold int64 = 23 * mb - maxContainerThreshold int64 = 1000 * mb -) - -// ImageLocality is a score plugin that favors nodes that already have requested pod container's images. -type ImageLocality struct { - handle framework.Handle -} - -var _ framework.ScorePlugin = &ImageLocality{} - -// Name is the name of the plugin used in the plugin registry and configurations. -const Name = names.ImageLocality - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *ImageLocality) Name() string { - return Name -} - -// Score invoked at the score extension point. -func (pl *ImageLocality) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - nodeInfos, err := pl.handle.SnapshotSharedLister().NodeInfos().List() - if err != nil { - return 0, framework.AsStatus(err) - } - totalNumNodes := len(nodeInfos) - - imageScores := sumImageScores(nodeInfo, pod, totalNumNodes) - score := calculatePriority(imageScores, len(pod.Spec.InitContainers)+len(pod.Spec.Containers)) - - return score, nil -} - -// ScoreExtensions of the Score plugin. -func (pl *ImageLocality) ScoreExtensions() framework.ScoreExtensions { - return nil -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, h framework.Handle) (framework.Plugin, error) { - return &ImageLocality{handle: h}, nil -} - -// calculatePriority returns the priority of a node. Given the sumScores of requested images on the node, the node's -// priority is obtained by scaling the maximum priority value with a ratio proportional to the sumScores. -func calculatePriority(sumScores int64, numContainers int) int64 { - maxThreshold := maxContainerThreshold * int64(numContainers) - if sumScores < minThreshold { - sumScores = minThreshold - } else if sumScores > maxThreshold { - sumScores = maxThreshold - } - - return framework.MaxNodeScore * (sumScores - minThreshold) / (maxThreshold - minThreshold) -} - -// sumImageScores returns the sum of image scores of all the containers that are already on the node. -// Each image receives a raw score of its size, scaled by scaledImageScore. The raw scores are later used to calculate -// the final score. -func sumImageScores(nodeInfo *framework.NodeInfo, pod *v1.Pod, totalNumNodes int) int64 { - var sum int64 - for _, container := range pod.Spec.InitContainers { - if state, ok := nodeInfo.ImageStates[normalizedImageName(container.Image)]; ok { - sum += scaledImageScore(state, totalNumNodes) - } - } - for _, container := range pod.Spec.Containers { - if state, ok := nodeInfo.ImageStates[normalizedImageName(container.Image)]; ok { - sum += scaledImageScore(state, totalNumNodes) - } - } - return sum -} - -// scaledImageScore returns an adaptively scaled score for the given state of an image. -// The size of the image is used as the base score, scaled by a factor which considers how much nodes the image has "spread" to. -// This heuristic aims to mitigate the undesirable "node heating problem", i.e., pods get assigned to the same or -// a few nodes due to image locality. -func scaledImageScore(imageState *framework.ImageStateSummary, totalNumNodes int) int64 { - spread := float64(imageState.NumNodes) / float64(totalNumNodes) - return int64(float64(imageState.Size) * spread) -} - -// normalizedImageName returns the CRI compliant name for a given image. -// TODO: cover the corner cases of missed matches, e.g, -// 1. Using Docker as runtime and docker.io/library/test:tag in pod spec, but only test:tag will present in node status -// 2. Using the implicit registry, i.e., test:tag or library/test:tag in pod spec but only docker.io/library/test:tag -// in node status; note that if users consistently use one registry format, this should not happen. -func normalizedImageName(name string) string { - if strings.LastIndex(name, ":") <= strings.LastIndex(name, "/") { - name = name + ":latest" - } - return name -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/filtering.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/filtering.go deleted file mode 100644 index 6d5106f02..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/filtering.go +++ /dev/null @@ -1,435 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package interpodaffinity - -import ( - "context" - "fmt" - "sync/atomic" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -const ( - // preFilterStateKey is the key in CycleState to InterPodAffinity pre-computed data for Filtering. - // Using the name of the plugin will likely help us avoid collisions with other plugins. - preFilterStateKey = "PreFilter" + Name - - // ErrReasonExistingAntiAffinityRulesNotMatch is used for ExistingPodsAntiAffinityRulesNotMatch predicate error. - ErrReasonExistingAntiAffinityRulesNotMatch = "node(s) didn't satisfy existing pods anti-affinity rules" - // ErrReasonAffinityRulesNotMatch is used for PodAffinityRulesNotMatch predicate error. - ErrReasonAffinityRulesNotMatch = "node(s) didn't match pod affinity rules" - // ErrReasonAntiAffinityRulesNotMatch is used for PodAntiAffinityRulesNotMatch predicate error. - ErrReasonAntiAffinityRulesNotMatch = "node(s) didn't match pod anti-affinity rules" -) - -// preFilterState computed at PreFilter and used at Filter. -type preFilterState struct { - // A map of topology pairs to the number of existing pods that has anti-affinity terms that match the "pod". - existingAntiAffinityCounts topologyToMatchedTermCount - // A map of topology pairs to the number of existing pods that match the affinity terms of the "pod". - affinityCounts topologyToMatchedTermCount - // A map of topology pairs to the number of existing pods that match the anti-affinity terms of the "pod". - antiAffinityCounts topologyToMatchedTermCount - // podInfo of the incoming pod. - podInfo *framework.PodInfo - // A copy of the incoming pod's namespace labels. - namespaceLabels labels.Set -} - -// Clone the prefilter state. -func (s *preFilterState) Clone() framework.StateData { - if s == nil { - return nil - } - - copy := preFilterState{} - copy.affinityCounts = s.affinityCounts.clone() - copy.antiAffinityCounts = s.antiAffinityCounts.clone() - copy.existingAntiAffinityCounts = s.existingAntiAffinityCounts.clone() - // No need to deep copy the podInfo because it shouldn't change. - copy.podInfo = s.podInfo - copy.namespaceLabels = s.namespaceLabels - return © -} - -// updateWithPod updates the preFilterState counters with the (anti)affinity matches for the given podInfo. -func (s *preFilterState) updateWithPod(pInfo *framework.PodInfo, node *v1.Node, multiplier int64) { - if s == nil { - return - } - - s.existingAntiAffinityCounts.updateWithAntiAffinityTerms(pInfo.RequiredAntiAffinityTerms, s.podInfo.Pod, s.namespaceLabels, node, multiplier) - s.affinityCounts.updateWithAffinityTerms(s.podInfo.RequiredAffinityTerms, pInfo.Pod, node, multiplier) - // The incoming pod's terms have the namespaceSelector merged into the namespaces, and so - // here we don't lookup the updated pod's namespace labels, hence passing nil for nsLabels. - s.antiAffinityCounts.updateWithAntiAffinityTerms(s.podInfo.RequiredAntiAffinityTerms, pInfo.Pod, nil, node, multiplier) -} - -type topologyPair struct { - key string - value string -} -type topologyToMatchedTermCount map[topologyPair]int64 - -func (m topologyToMatchedTermCount) merge(toMerge topologyToMatchedTermCount) { - for pair, count := range toMerge { - m[pair] += count - } -} - -func (m topologyToMatchedTermCount) mergeWithList(toMerge topologyToMatchedTermCountList) { - for _, tmtc := range toMerge { - m[tmtc.topologyPair] += tmtc.count - } -} - -func (m topologyToMatchedTermCount) clone() topologyToMatchedTermCount { - copy := make(topologyToMatchedTermCount, len(m)) - copy.merge(m) - return copy -} - -func (m topologyToMatchedTermCount) update(node *v1.Node, tk string, value int64) { - if tv, ok := node.Labels[tk]; ok { - pair := topologyPair{key: tk, value: tv} - m[pair] += value - // value could be negative, hence we delete the entry if it is down to zero. - if m[pair] == 0 { - delete(m, pair) - } - } -} - -// updates the topologyToMatchedTermCount map with the specified value -// for each affinity term if "targetPod" matches ALL terms. -func (m topologyToMatchedTermCount) updateWithAffinityTerms( - terms []framework.AffinityTerm, pod *v1.Pod, node *v1.Node, value int64) { - if podMatchesAllAffinityTerms(terms, pod) { - for _, t := range terms { - m.update(node, t.TopologyKey, value) - } - } -} - -// updates the topologyToMatchedTermCount map with the specified value -// for each anti-affinity term matched the target pod. -func (m topologyToMatchedTermCount) updateWithAntiAffinityTerms(terms []framework.AffinityTerm, pod *v1.Pod, nsLabels labels.Set, node *v1.Node, value int64) { - // Check anti-affinity terms. - for _, t := range terms { - if t.Matches(pod, nsLabels) { - m.update(node, t.TopologyKey, value) - } - } -} - -// topologyToMatchedTermCountList is a slice equivalent of topologyToMatchedTermCount map. -// The use of slice improves the performance of PreFilter, -// especially due to faster iteration when merging than with topologyToMatchedTermCount. -type topologyToMatchedTermCountList []topologyPairCount - -type topologyPairCount struct { - topologyPair topologyPair - count int64 -} - -func (m *topologyToMatchedTermCountList) append(node *v1.Node, tk string, value int64) { - if tv, ok := node.Labels[tk]; ok { - pair := topologyPair{key: tk, value: tv} - *m = append(*m, topologyPairCount{ - topologyPair: pair, - count: value, - }) - } -} - -// appends the specified value to the topologyToMatchedTermCountList -// for each affinity term if "targetPod" matches ALL terms. -func (m *topologyToMatchedTermCountList) appendWithAffinityTerms( - terms []framework.AffinityTerm, pod *v1.Pod, node *v1.Node, value int64) { - if podMatchesAllAffinityTerms(terms, pod) { - for _, t := range terms { - m.append(node, t.TopologyKey, value) - } - } -} - -// appends the specified value to the topologyToMatchedTermCountList -// for each anti-affinity term matched the target pod. -func (m *topologyToMatchedTermCountList) appendWithAntiAffinityTerms(terms []framework.AffinityTerm, pod *v1.Pod, nsLabels labels.Set, node *v1.Node, value int64) { - // Check anti-affinity terms. - for _, t := range terms { - if t.Matches(pod, nsLabels) { - m.append(node, t.TopologyKey, value) - } - } -} - -// returns true IFF the given pod matches all the given terms. -func podMatchesAllAffinityTerms(terms []framework.AffinityTerm, pod *v1.Pod) bool { - if len(terms) == 0 { - return false - } - for _, t := range terms { - // The incoming pod NamespaceSelector was merged into the Namespaces set, and so - // we are not explicitly passing in namespace labels. - if !t.Matches(pod, nil) { - return false - } - } - return true -} - -// calculates the following for each existing pod on each node: -// 1. Whether it has PodAntiAffinity -// 2. Whether any AntiAffinityTerm matches the incoming pod -func (pl *InterPodAffinity) getExistingAntiAffinityCounts(ctx context.Context, pod *v1.Pod, nsLabels labels.Set, nodes []*framework.NodeInfo) topologyToMatchedTermCount { - antiAffinityCountsList := make([]topologyToMatchedTermCountList, len(nodes)) - index := int32(-1) - processNode := func(i int) { - nodeInfo := nodes[i] - node := nodeInfo.Node() - - antiAffinityCounts := make(topologyToMatchedTermCountList, 0) - for _, existingPod := range nodeInfo.PodsWithRequiredAntiAffinity { - antiAffinityCounts.appendWithAntiAffinityTerms(existingPod.RequiredAntiAffinityTerms, pod, nsLabels, node, 1) - } - if len(antiAffinityCounts) != 0 { - antiAffinityCountsList[atomic.AddInt32(&index, 1)] = antiAffinityCounts - } - } - pl.parallelizer.Until(ctx, len(nodes), processNode, pl.Name()) - - result := make(topologyToMatchedTermCount) - // Traditional for loop is slightly faster in this case than its "for range" equivalent. - for i := 0; i <= int(index); i++ { - result.mergeWithList(antiAffinityCountsList[i]) - } - - return result -} - -// finds existing Pods that match affinity terms of the incoming pod's (anti)affinity terms. -// It returns a topologyToMatchedTermCount that are checked later by the affinity -// predicate. With this topologyToMatchedTermCount available, the affinity predicate does not -// need to check all the pods in the cluster. -func (pl *InterPodAffinity) getIncomingAffinityAntiAffinityCounts(ctx context.Context, podInfo *framework.PodInfo, allNodes []*framework.NodeInfo) (topologyToMatchedTermCount, topologyToMatchedTermCount) { - affinityCounts := make(topologyToMatchedTermCount) - antiAffinityCounts := make(topologyToMatchedTermCount) - if len(podInfo.RequiredAffinityTerms) == 0 && len(podInfo.RequiredAntiAffinityTerms) == 0 { - return affinityCounts, antiAffinityCounts - } - - affinityCountsList := make([]topologyToMatchedTermCountList, len(allNodes)) - antiAffinityCountsList := make([]topologyToMatchedTermCountList, len(allNodes)) - index := int32(-1) - processNode := func(i int) { - nodeInfo := allNodes[i] - node := nodeInfo.Node() - - affinity := make(topologyToMatchedTermCountList, 0) - antiAffinity := make(topologyToMatchedTermCountList, 0) - for _, existingPod := range nodeInfo.Pods { - affinity.appendWithAffinityTerms(podInfo.RequiredAffinityTerms, existingPod.Pod, node, 1) - // The incoming pod's terms have the namespaceSelector merged into the namespaces, and so - // here we don't lookup the existing pod's namespace labels, hence passing nil for nsLabels. - antiAffinity.appendWithAntiAffinityTerms(podInfo.RequiredAntiAffinityTerms, existingPod.Pod, nil, node, 1) - } - - if len(affinity) > 0 || len(antiAffinity) > 0 { - k := atomic.AddInt32(&index, 1) - affinityCountsList[k] = affinity - antiAffinityCountsList[k] = antiAffinity - } - } - pl.parallelizer.Until(ctx, len(allNodes), processNode, pl.Name()) - - for i := 0; i <= int(index); i++ { - affinityCounts.mergeWithList(affinityCountsList[i]) - antiAffinityCounts.mergeWithList(antiAffinityCountsList[i]) - } - - return affinityCounts, antiAffinityCounts -} - -// PreFilter invoked at the prefilter extension point. -func (pl *InterPodAffinity) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - var allNodes []*framework.NodeInfo - var nodesWithRequiredAntiAffinityPods []*framework.NodeInfo - var err error - if allNodes, err = pl.sharedLister.NodeInfos().List(); err != nil { - return nil, framework.AsStatus(fmt.Errorf("failed to list NodeInfos: %w", err)) - } - if nodesWithRequiredAntiAffinityPods, err = pl.sharedLister.NodeInfos().HavePodsWithRequiredAntiAffinityList(); err != nil { - return nil, framework.AsStatus(fmt.Errorf("failed to list NodeInfos with pods with affinity: %w", err)) - } - - s := &preFilterState{} - - if s.podInfo, err = framework.NewPodInfo(pod); err != nil { - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, fmt.Sprintf("parsing pod: %+v", err)) - } - - for i := range s.podInfo.RequiredAffinityTerms { - if err := pl.mergeAffinityTermNamespacesIfNotEmpty(&s.podInfo.RequiredAffinityTerms[i]); err != nil { - return nil, framework.AsStatus(err) - } - } - for i := range s.podInfo.RequiredAntiAffinityTerms { - if err := pl.mergeAffinityTermNamespacesIfNotEmpty(&s.podInfo.RequiredAntiAffinityTerms[i]); err != nil { - return nil, framework.AsStatus(err) - } - } - logger := klog.FromContext(ctx) - s.namespaceLabels = GetNamespaceLabelsSnapshot(logger, pod.Namespace, pl.nsLister) - - s.existingAntiAffinityCounts = pl.getExistingAntiAffinityCounts(ctx, pod, s.namespaceLabels, nodesWithRequiredAntiAffinityPods) - s.affinityCounts, s.antiAffinityCounts = pl.getIncomingAffinityAntiAffinityCounts(ctx, s.podInfo, allNodes) - - if len(s.existingAntiAffinityCounts) == 0 && len(s.podInfo.RequiredAffinityTerms) == 0 && len(s.podInfo.RequiredAntiAffinityTerms) == 0 { - return nil, framework.NewStatus(framework.Skip) - } - - cycleState.Write(preFilterStateKey, s) - return nil, nil -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (pl *InterPodAffinity) PreFilterExtensions() framework.PreFilterExtensions { - return pl -} - -// AddPod from pre-computed data in cycleState. -func (pl *InterPodAffinity) AddPod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToAdd *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - state, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - state.updateWithPod(podInfoToAdd, nodeInfo.Node(), 1) - return nil -} - -// RemovePod from pre-computed data in cycleState. -func (pl *InterPodAffinity) RemovePod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToRemove *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - state, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - state.updateWithPod(podInfoToRemove, nodeInfo.Node(), -1) - return nil -} - -func getPreFilterState(cycleState *framework.CycleState) (*preFilterState, error) { - c, err := cycleState.Read(preFilterStateKey) - if err != nil { - // preFilterState doesn't exist, likely PreFilter wasn't invoked. - return nil, fmt.Errorf("error reading %q from cycleState: %w", preFilterStateKey, err) - } - - s, ok := c.(*preFilterState) - if !ok { - return nil, fmt.Errorf("%+v convert to interpodaffinity.state error", c) - } - return s, nil -} - -// Checks if scheduling the pod onto this node would break any anti-affinity -// terms indicated by the existing pods. -func satisfyExistingPodsAntiAffinity(state *preFilterState, nodeInfo *framework.NodeInfo) bool { - if len(state.existingAntiAffinityCounts) > 0 { - // Iterate over topology pairs to get any of the pods being affected by - // the scheduled pod anti-affinity terms - for topologyKey, topologyValue := range nodeInfo.Node().Labels { - tp := topologyPair{key: topologyKey, value: topologyValue} - if state.existingAntiAffinityCounts[tp] > 0 { - return false - } - } - } - return true -} - -// Checks if the node satisfies the incoming pod's anti-affinity rules. -func satisfyPodAntiAffinity(state *preFilterState, nodeInfo *framework.NodeInfo) bool { - if len(state.antiAffinityCounts) > 0 { - for _, term := range state.podInfo.RequiredAntiAffinityTerms { - if topologyValue, ok := nodeInfo.Node().Labels[term.TopologyKey]; ok { - tp := topologyPair{key: term.TopologyKey, value: topologyValue} - if state.antiAffinityCounts[tp] > 0 { - return false - } - } - } - } - return true -} - -// Checks if the node satisfies the incoming pod's affinity rules. -func satisfyPodAffinity(state *preFilterState, nodeInfo *framework.NodeInfo) bool { - podsExist := true - for _, term := range state.podInfo.RequiredAffinityTerms { - if topologyValue, ok := nodeInfo.Node().Labels[term.TopologyKey]; ok { - tp := topologyPair{key: term.TopologyKey, value: topologyValue} - if state.affinityCounts[tp] <= 0 { - podsExist = false - } - } else { - // All topology labels must exist on the node. - return false - } - } - - if !podsExist { - // This pod may be the first pod in a series that have affinity to themselves. In order - // to not leave such pods in pending state forever, we check that if no other pod - // in the cluster matches the namespace and selector of this pod, the pod matches - // its own terms, and the node has all the requested topologies, then we allow the pod - // to pass the affinity check. - if len(state.affinityCounts) == 0 && podMatchesAllAffinityTerms(state.podInfo.RequiredAffinityTerms, state.podInfo.Pod) { - return true - } - return false - } - return true -} - -// Filter invoked at the filter extension point. -// It checks if a pod can be scheduled on the specified node with pod affinity/anti-affinity configuration. -func (pl *InterPodAffinity) Filter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - - state, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - - if !satisfyPodAffinity(state, nodeInfo) { - return framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonAffinityRulesNotMatch) - } - - if !satisfyPodAntiAffinity(state, nodeInfo) { - return framework.NewStatus(framework.Unschedulable, ErrReasonAntiAffinityRulesNotMatch) - } - - if !satisfyExistingPodsAntiAffinity(state, nodeInfo) { - return framework.NewStatus(framework.Unschedulable, ErrReasonExistingAntiAffinityRulesNotMatch) - } - - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go deleted file mode 100644 index 78d6d65e8..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/plugin.go +++ /dev/null @@ -1,299 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package interpodaffinity - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - listersv1 "k8s.io/client-go/listers/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// Name is the name of the plugin used in the plugin registry and configurations. -const Name = names.InterPodAffinity - -var _ framework.PreFilterPlugin = &InterPodAffinity{} -var _ framework.FilterPlugin = &InterPodAffinity{} -var _ framework.PreScorePlugin = &InterPodAffinity{} -var _ framework.ScorePlugin = &InterPodAffinity{} -var _ framework.EnqueueExtensions = &InterPodAffinity{} - -// InterPodAffinity is a plugin that checks inter pod affinity -type InterPodAffinity struct { - parallelizer parallelize.Parallelizer - args config.InterPodAffinityArgs - sharedLister framework.SharedLister - nsLister listersv1.NamespaceLister - enableSchedulingQueueHint bool -} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *InterPodAffinity) Name() string { - return Name -} - -// EventsToRegister returns the possible events that may make a failed Pod -// schedulable -func (pl *InterPodAffinity) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // A note about UpdateNodeTaint event: - // Ideally, it's supposed to register only Add | UpdateNodeLabel because UpdateNodeTaint will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeLabel | framework.UpdateNodeTaint - if pl.enableSchedulingQueueHint { - // When QueueingHint is enabled, we don't use preCheck and we don't need to register UpdateNodeTaint event. - nodeActionType = framework.Add | framework.UpdateNodeLabel - } - return []framework.ClusterEventWithHint{ - // All ActionType includes the following events: - // - Delete. An unschedulable Pod may fail due to violating an existing Pod's anti-affinity constraints, - // deleting an existing Pod may make it schedulable. - // - UpdatePodLabel. Updating on an existing Pod's labels (e.g., removal) may make - // an unschedulable Pod schedulable. - // - Add. An unschedulable Pod may fail due to violating pod-affinity constraints, - // adding an assigned Pod may make it schedulable. - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.Add | framework.UpdatePodLabel | framework.Delete}, QueueingHintFn: pl.isSchedulableAfterPodChange}, - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}, QueueingHintFn: pl.isSchedulableAfterNodeChange}, - }, nil -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, plArgs runtime.Object, h framework.Handle, fts feature.Features) (framework.Plugin, error) { - if h.SnapshotSharedLister() == nil { - return nil, fmt.Errorf("SnapshotSharedlister is nil") - } - args, err := getArgs(plArgs) - if err != nil { - return nil, err - } - if err := validation.ValidateInterPodAffinityArgs(nil, &args); err != nil { - return nil, err - } - pl := &InterPodAffinity{ - parallelizer: h.Parallelizer(), - args: args, - sharedLister: h.SnapshotSharedLister(), - nsLister: h.SharedInformerFactory().Core().V1().Namespaces().Lister(), - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - } - - return pl, nil -} - -func getArgs(obj runtime.Object) (config.InterPodAffinityArgs, error) { - ptr, ok := obj.(*config.InterPodAffinityArgs) - if !ok { - return config.InterPodAffinityArgs{}, fmt.Errorf("want args to be of type InterPodAffinityArgs, got %T", obj) - } - return *ptr, nil -} - -// Updates Namespaces with the set of namespaces identified by NamespaceSelector. -// If successful, NamespaceSelector is set to nil. -// The assumption is that the term is for an incoming pod, in which case -// namespaceSelector is either unrolled into Namespaces (and so the selector -// is set to Nothing()) or is Empty(), which means match everything. Therefore, -// there when matching against this term, there is no need to lookup the existing -// pod's namespace labels to match them against term's namespaceSelector explicitly. -func (pl *InterPodAffinity) mergeAffinityTermNamespacesIfNotEmpty(at *framework.AffinityTerm) error { - if at.NamespaceSelector.Empty() { - return nil - } - ns, err := pl.nsLister.List(at.NamespaceSelector) - if err != nil { - return err - } - for _, n := range ns { - at.Namespaces.Insert(n.Name) - } - at.NamespaceSelector = labels.Nothing() - return nil -} - -// GetNamespaceLabelsSnapshot returns a snapshot of the labels associated with -// the namespace. -func GetNamespaceLabelsSnapshot(logger klog.Logger, ns string, nsLister listersv1.NamespaceLister) (nsLabels labels.Set) { - podNS, err := nsLister.Get(ns) - if err == nil { - // Create and return snapshot of the labels. - return labels.Merge(podNS.Labels, nil) - } - logger.V(3).Info("getting namespace, assuming empty set of namespace labels", "namespace", ns, "err", err) - return -} - -func (pl *InterPodAffinity) isSchedulableAfterPodChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalPod, modifiedPod, err := util.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - if (modifiedPod != nil && modifiedPod.Spec.NodeName == "") || (originalPod != nil && originalPod.Spec.NodeName == "") { - logger.V(5).Info("the added/updated/deleted pod is unscheduled, so it doesn't make the target pod schedulable", - "pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - terms, err := framework.GetAffinityTerms(pod, framework.GetPodAffinityTerms(pod.Spec.Affinity)) - if err != nil { - return framework.Queue, err - } - - antiTerms, err := framework.GetAffinityTerms(pod, framework.GetPodAntiAffinityTerms(pod.Spec.Affinity)) - if err != nil { - return framework.Queue, err - } - - // Pod is updated. Return Queue when the updated pod matching the target pod's affinity or not matching anti-affinity. - // Note that, we don't need to check each affinity individually when the Pod has more than one affinity - // because the current PodAffinity looks for a **single** existing pod that can satisfy **all** the terms of inter-pod affinity of an incoming pod. - if modifiedPod != nil && originalPod != nil { - if !podMatchesAllAffinityTerms(terms, originalPod) && podMatchesAllAffinityTerms(terms, modifiedPod) { - logger.V(5).Info("a scheduled pod was updated to match the target pod's affinity, and the pod may be schedulable now", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - if podMatchesAllAffinityTerms(antiTerms, originalPod) && !podMatchesAllAffinityTerms(antiTerms, modifiedPod) { - logger.V(5).Info("a scheduled pod was updated not to match the target pod's anti affinity, and the pod may be schedulable now", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - logger.V(5).Info("a scheduled pod was updated but it doesn't match the target pod's affinity or does match the target pod's anti-affinity", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - // Pod is added. Return Queue when the added pod matching the target pod's affinity. - if modifiedPod != nil { - if podMatchesAllAffinityTerms(terms, modifiedPod) { - logger.V(5).Info("a scheduled pod was added and it matches the target pod's affinity", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - logger.V(5).Info("a scheduled pod was added and it doesn't match the target pod's affinity", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - // Pod is deleted. Return Queue when the deleted pod matching the target pod's anti-affinity. - if !podMatchesAllAffinityTerms(antiTerms, originalPod) { - logger.V(5).Info("a scheduled pod was deleted but it doesn't match the target pod's anti-affinity", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - logger.V(5).Info("a scheduled pod was deleted and it matches the target pod's anti-affinity. The pod may be schedulable now", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.Queue, nil -} - -func (pl *InterPodAffinity) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalNode, modifiedNode, err := util.As[*v1.Node](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - terms, err := framework.GetAffinityTerms(pod, framework.GetPodAffinityTerms(pod.Spec.Affinity)) - if err != nil { - return framework.Queue, err - } - - // When queuing this Pod: - // - 1. A new node is added with the pod affinity topologyKey, the pod may become schedulable. - // - 2. The original node does not have the pod affinity topologyKey but the modified node does, the pod may become schedulable. - // - 3. Both the original and modified nodes have the pod affinity topologyKey and they differ, the pod may become schedulable. - for _, term := range terms { - if originalNode == nil { - if _, ok := modifiedNode.Labels[term.TopologyKey]; ok { - // Case 1: A new node is added with the pod affinity topologyKey. - logger.V(5).Info("A node with a matched pod affinity topologyKey was added and it may make the pod schedulable", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - continue - } - originalTopologyValue, originalHasKey := originalNode.Labels[term.TopologyKey] - modifiedTopologyValue, modifiedHasKey := modifiedNode.Labels[term.TopologyKey] - - if !originalHasKey && modifiedHasKey { - // Case 2: Original node does not have the pod affinity topologyKey, but the modified node does. - logger.V(5).Info("A node got updated to have the topology key of pod affinity, which may make the pod schedulable", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - - if originalHasKey && modifiedHasKey && (originalTopologyValue != modifiedTopologyValue) { - // Case 3: Both nodes have the pod affinity topologyKey, but the values differ. - logger.V(5).Info("A node is moved to a different domain of pod affinity, which may make the pod schedulable", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - } - - antiTerms, err := framework.GetAffinityTerms(pod, framework.GetPodAntiAffinityTerms(pod.Spec.Affinity)) - if err != nil { - return framework.Queue, err - } - - // When queuing this Pod: - // - 1. A new node is added, the pod may become schedulable. - // - 2. The original node have the pod anti-affinity topologyKey but the modified node does not, the pod may become schedulable. - // - 3. Both the original and modified nodes have the pod anti-affinity topologyKey and they differ, the pod may become schedulable. - for _, term := range antiTerms { - if originalNode == nil { - // Case 1: A new node is added. - // We always requeue the Pod with anti-affinity because: - // - the node without the topology key is always allowed to have a Pod with anti-affinity. - // - the addition of a node with the topology key makes Pods schedulable only when the topology it joins doesn't have any Pods that the Pod hates. - // But, it's out-of-scope of this QHint to check which Pods are in the topology this Node is in. - logger.V(5).Info("A node was added and it may make the pod schedulable", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - - originalTopologyValue, originalHasKey := originalNode.Labels[term.TopologyKey] - modifiedTopologyValue, modifiedHasKey := modifiedNode.Labels[term.TopologyKey] - - if originalHasKey && !modifiedHasKey { - // Case 2: The original node have the pod anti-affinity topologyKey but the modified node does not. - // Note that we don't need to check the opposite case (!originalHasKey && modifiedHasKey) - // because the node without the topology label can always accept pods with pod anti-affinity. - logger.V(5).Info("A node got updated to not have the topology key of pod anti-affinity, which may make the pod schedulable", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - - if originalHasKey && modifiedHasKey && (originalTopologyValue != modifiedTopologyValue) { - // Case 3: Both nodes have the pod anti-affinity topologyKey, but the values differ. - logger.V(5).Info("A node is moved to a different domain of pod anti-affinity, which may make the pod schedulable", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - } - logger.V(5).Info("a node is added/updated but doesn't have any topologyKey which matches pod affinity/anti-affinity", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go deleted file mode 100644 index 126f54a47..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity/scoring.go +++ /dev/null @@ -1,294 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package interpodaffinity - -import ( - "context" - "fmt" - "math" - "sync/atomic" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// preScoreStateKey is the key in CycleState to InterPodAffinity pre-computed data for Scoring. -const preScoreStateKey = "PreScore" + Name - -type scoreMap map[string]map[string]int64 - -// preScoreState computed at PreScore and used at Score. -type preScoreState struct { - topologyScore scoreMap - podInfo *framework.PodInfo - // A copy of the incoming pod's namespace labels. - namespaceLabels labels.Set -} - -// Clone implements the mandatory Clone interface. We don't really copy the data since -// there is no need for that. -func (s *preScoreState) Clone() framework.StateData { - return s -} - -func (m scoreMap) processTerm(term *framework.AffinityTerm, weight int32, pod *v1.Pod, nsLabels labels.Set, node *v1.Node, multiplier int32) { - if term.Matches(pod, nsLabels) { - if tpValue, tpValueExist := node.Labels[term.TopologyKey]; tpValueExist { - if m[term.TopologyKey] == nil { - m[term.TopologyKey] = make(map[string]int64) - } - m[term.TopologyKey][tpValue] += int64(weight * multiplier) - } - } -} - -func (m scoreMap) processTerms(terms []framework.WeightedAffinityTerm, pod *v1.Pod, nsLabels labels.Set, node *v1.Node, multiplier int32) { - for _, term := range terms { - m.processTerm(&term.AffinityTerm, term.Weight, pod, nsLabels, node, multiplier) - } -} - -func (m scoreMap) append(other scoreMap) { - for topology, oScores := range other { - scores := m[topology] - if scores == nil { - m[topology] = oScores - continue - } - for k, v := range oScores { - scores[k] += v - } - } -} - -func (pl *InterPodAffinity) processExistingPod( - state *preScoreState, - existingPod *framework.PodInfo, - existingPodNodeInfo *framework.NodeInfo, - incomingPod *v1.Pod, - topoScore scoreMap, -) { - existingPodNode := existingPodNodeInfo.Node() - if len(existingPodNode.Labels) == 0 { - return - } - - // For every soft pod affinity term of , if matches the term, - // increment for every node in the cluster with the same - // value as that of `s node by the term`s weight. - // Note that the incoming pod's terms have the namespaceSelector merged into the namespaces, and so - // here we don't lookup the existing pod's namespace labels, hence passing nil for nsLabels. - topoScore.processTerms(state.podInfo.PreferredAffinityTerms, existingPod.Pod, nil, existingPodNode, 1) - - // For every soft pod anti-affinity term of , if matches the term, - // decrement for every node in the cluster with the same - // value as that of `s node by the term`s weight. - // Note that the incoming pod's terms have the namespaceSelector merged into the namespaces, and so - // here we don't lookup the existing pod's namespace labels, hence passing nil for nsLabels. - topoScore.processTerms(state.podInfo.PreferredAntiAffinityTerms, existingPod.Pod, nil, existingPodNode, -1) - - // For every hard pod affinity term of , if matches the term, - // increment for every node in the cluster with the same - // value as that of 's node by the constant - if pl.args.HardPodAffinityWeight > 0 && len(existingPodNode.Labels) != 0 { - for _, t := range existingPod.RequiredAffinityTerms { - topoScore.processTerm(&t, pl.args.HardPodAffinityWeight, incomingPod, state.namespaceLabels, existingPodNode, 1) - } - } - - // For every soft pod affinity term of , if matches the term, - // increment for every node in the cluster with the same - // value as that of 's node by the term's weight. - topoScore.processTerms(existingPod.PreferredAffinityTerms, incomingPod, state.namespaceLabels, existingPodNode, 1) - - // For every soft pod anti-affinity term of , if matches the term, - // decrement for every node in the cluster with the same - // value as that of 's node by the term's weight. - topoScore.processTerms(existingPod.PreferredAntiAffinityTerms, incomingPod, state.namespaceLabels, existingPodNode, -1) -} - -// PreScore builds and writes cycle state used by Score and NormalizeScore. -func (pl *InterPodAffinity) PreScore( - pCtx context.Context, - cycleState *framework.CycleState, - pod *v1.Pod, - nodes []*framework.NodeInfo, -) *framework.Status { - - if pl.sharedLister == nil { - return framework.NewStatus(framework.Error, "empty shared lister in InterPodAffinity PreScore") - } - - affinity := pod.Spec.Affinity - hasPreferredAffinityConstraints := affinity != nil && affinity.PodAffinity != nil && len(affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution) > 0 - hasPreferredAntiAffinityConstraints := affinity != nil && affinity.PodAntiAffinity != nil && len(affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution) > 0 - hasConstraints := hasPreferredAffinityConstraints || hasPreferredAntiAffinityConstraints - - // Optionally ignore calculating preferences of existing pods' affinity rules - // if the incoming pod has no inter-pod affinities. - if pl.args.IgnorePreferredTermsOfExistingPods && !hasConstraints { - return framework.NewStatus(framework.Skip) - } - - // Unless the pod being scheduled has preferred affinity terms, we only - // need to process nodes hosting pods with affinity. - var allNodes []*framework.NodeInfo - var err error - if hasConstraints { - allNodes, err = pl.sharedLister.NodeInfos().List() - if err != nil { - return framework.AsStatus(fmt.Errorf("failed to get all nodes from shared lister: %w", err)) - } - } else { - allNodes, err = pl.sharedLister.NodeInfos().HavePodsWithAffinityList() - if err != nil { - return framework.AsStatus(fmt.Errorf("failed to get pods with affinity list: %w", err)) - } - } - - state := &preScoreState{ - topologyScore: make(map[string]map[string]int64), - } - - if state.podInfo, err = framework.NewPodInfo(pod); err != nil { - // Ideally we never reach here, because errors will be caught by PreFilter - return framework.AsStatus(fmt.Errorf("failed to parse pod: %w", err)) - } - - for i := range state.podInfo.PreferredAffinityTerms { - if err := pl.mergeAffinityTermNamespacesIfNotEmpty(&state.podInfo.PreferredAffinityTerms[i].AffinityTerm); err != nil { - return framework.AsStatus(fmt.Errorf("updating PreferredAffinityTerms: %w", err)) - } - } - for i := range state.podInfo.PreferredAntiAffinityTerms { - if err := pl.mergeAffinityTermNamespacesIfNotEmpty(&state.podInfo.PreferredAntiAffinityTerms[i].AffinityTerm); err != nil { - return framework.AsStatus(fmt.Errorf("updating PreferredAntiAffinityTerms: %w", err)) - } - } - logger := klog.FromContext(pCtx) - state.namespaceLabels = GetNamespaceLabelsSnapshot(logger, pod.Namespace, pl.nsLister) - - topoScores := make([]scoreMap, len(allNodes)) - index := int32(-1) - processNode := func(i int) { - nodeInfo := allNodes[i] - - // Unless the pod being scheduled has preferred affinity terms, we only - // need to process pods with affinity in the node. - podsToProcess := nodeInfo.PodsWithAffinity - if hasConstraints { - // We need to process all the pods. - podsToProcess = nodeInfo.Pods - } - - topoScore := make(scoreMap) - for _, existingPod := range podsToProcess { - pl.processExistingPod(state, existingPod, nodeInfo, pod, topoScore) - } - if len(topoScore) > 0 { - topoScores[atomic.AddInt32(&index, 1)] = topoScore - } - } - pl.parallelizer.Until(pCtx, len(allNodes), processNode, pl.Name()) - - if index == -1 { - return framework.NewStatus(framework.Skip) - } - - for i := 0; i <= int(index); i++ { - state.topologyScore.append(topoScores[i]) - } - - cycleState.Write(preScoreStateKey, state) - return nil -} - -func getPreScoreState(cycleState *framework.CycleState) (*preScoreState, error) { - c, err := cycleState.Read(preScoreStateKey) - if err != nil { - return nil, fmt.Errorf("failed to read %q from cycleState: %w", preScoreStateKey, err) - } - - s, ok := c.(*preScoreState) - if !ok { - return nil, fmt.Errorf("%+v convert to interpodaffinity.preScoreState error", c) - } - return s, nil -} - -// Score invoked at the Score extension point. -// The "score" returned in this function is the sum of weights got from cycleState which have its topologyKey matching with the node's labels. -// it is normalized later. -// Note: the returned "score" is positive for pod-affinity, and negative for pod-antiaffinity. -func (pl *InterPodAffinity) Score(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - node := nodeInfo.Node() - - s, err := getPreScoreState(cycleState) - if err != nil { - return 0, framework.AsStatus(err) - } - var score int64 - for tpKey, tpValues := range s.topologyScore { - if v, exist := node.Labels[tpKey]; exist { - score += tpValues[v] - } - } - - return score, nil -} - -// NormalizeScore normalizes the score for each filteredNode. -func (pl *InterPodAffinity) NormalizeScore(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status { - s, err := getPreScoreState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - if len(s.topologyScore) == 0 { - return nil - } - - var minCount int64 = math.MaxInt64 - var maxCount int64 = math.MinInt64 - for i := range scores { - score := scores[i].Score - if score > maxCount { - maxCount = score - } - if score < minCount { - minCount = score - } - } - - maxMinDiff := maxCount - minCount - for i := range scores { - fScore := float64(0) - if maxMinDiff > 0 { - fScore = float64(framework.MaxNodeScore) * (float64(scores[i].Score-minCount) / float64(maxMinDiff)) - } - - scores[i].Score = int64(fScore) - } - - return nil -} - -// ScoreExtensions of the Score plugin. -func (pl *InterPodAffinity) ScoreExtensions() framework.ScoreExtensions { - return pl -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go deleted file mode 100644 index a3cf13423..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/names/names.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package names - -const ( - PrioritySort = "PrioritySort" - DefaultBinder = "DefaultBinder" - DefaultPreemption = "DefaultPreemption" - DynamicResources = "DynamicResources" - ImageLocality = "ImageLocality" - InterPodAffinity = "InterPodAffinity" - NodeAffinity = "NodeAffinity" - NodeName = "NodeName" - NodePorts = "NodePorts" - NodeResourcesBalancedAllocation = "NodeResourcesBalancedAllocation" - NodeResourcesFit = "NodeResourcesFit" - NodeUnschedulable = "NodeUnschedulable" - NodeVolumeLimits = "NodeVolumeLimits" - PodTopologySpread = "PodTopologySpread" - SchedulingGates = "SchedulingGates" - TaintToleration = "TaintToleration" - VolumeBinding = "VolumeBinding" - VolumeRestrictions = "VolumeRestrictions" - VolumeZone = "VolumeZone" -) diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity.go deleted file mode 100644 index f63efb616..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity/node_affinity.go +++ /dev/null @@ -1,364 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package nodeaffinity - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// NodeAffinity is a plugin that checks if a pod node selector matches the node label. -type NodeAffinity struct { - handle framework.Handle - addedNodeSelector *nodeaffinity.NodeSelector - addedPrefSchedTerms *nodeaffinity.PreferredSchedulingTerms - enableSchedulingQueueHint bool -} - -var _ framework.PreFilterPlugin = &NodeAffinity{} -var _ framework.FilterPlugin = &NodeAffinity{} -var _ framework.PreScorePlugin = &NodeAffinity{} -var _ framework.ScorePlugin = &NodeAffinity{} -var _ framework.EnqueueExtensions = &NodeAffinity{} - -const ( - // Name is the name of the plugin used in the plugin registry and configurations. - Name = names.NodeAffinity - - // preScoreStateKey is the key in CycleState to NodeAffinity pre-computed data for Scoring. - preScoreStateKey = "PreScore" + Name - - // preFilterStateKey is the key in CycleState to NodeAffinity pre-compute data for Filtering. - preFilterStateKey = "PreFilter" + Name - - // ErrReasonPod is the reason for Pod's node affinity/selector not matching. - ErrReasonPod = "node(s) didn't match Pod's node affinity/selector" - - // errReasonEnforced is the reason for added node affinity not matching. - errReasonEnforced = "node(s) didn't match scheduler-enforced node affinity" - - // errReasonConflict is the reason for pod's conflicting affinity rules. - errReasonConflict = "pod affinity terms conflict" -) - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *NodeAffinity) Name() string { - return Name -} - -type preFilterState struct { - requiredNodeSelectorAndAffinity nodeaffinity.RequiredNodeAffinity -} - -// Clone just returns the same state because it is not affected by pod additions or deletions. -func (s *preFilterState) Clone() framework.StateData { - return s -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *NodeAffinity) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // A note about UpdateNodeTaint event: - // Ideally, it's supposed to register only Add | UpdateNodeLabel because UpdateNodeTaint will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeLabel | framework.UpdateNodeTaint - if pl.enableSchedulingQueueHint { - // preCheck is not used when QHint is enabled, and hence we can use UpdateNodeLabel instead of Update. - nodeActionType = framework.Add | framework.UpdateNodeLabel - } - - return []framework.ClusterEventWithHint{ - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}, QueueingHintFn: pl.isSchedulableAfterNodeChange}, - }, nil -} - -// isSchedulableAfterNodeChange is invoked whenever a node changed. It checks whether -// that change made a previously unschedulable pod schedulable. -func (pl *NodeAffinity) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalNode, modifiedNode, err := util.As[*v1.Node](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - if pl.addedNodeSelector != nil && !pl.addedNodeSelector.Match(modifiedNode) { - logger.V(4).Info("added or modified node didn't match scheduler-enforced node affinity and this event won't make the Pod schedulable", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil - } - - requiredNodeAffinity := nodeaffinity.GetRequiredNodeAffinity(pod) - isMatched, err := requiredNodeAffinity.Match(modifiedNode) - if err != nil { - return framework.Queue, err - } - if !isMatched { - logger.V(5).Info("node was created or updated, but the pod's NodeAffinity doesn't match", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil - } - // Since the node was added and it matches the pod's affinity criteria, we can unblock it. - if originalNode == nil { - logger.V(5).Info("node was created, and matches with the pod's NodeAffinity", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - // At this point we know the operation is update so we can narrow down the criteria to unmatch -> match changes only - // (necessary affinity label was added to the node in this case). - wasMatched, err := requiredNodeAffinity.Match(originalNode) - if err != nil { - return framework.Queue, err - } - if wasMatched { - logger.V(5).Info("node updated, but the pod's NodeAffinity hasn't changed", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil - } - logger.V(5).Info("node was updated and the pod's NodeAffinity changed to matched", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil -} - -// PreFilter builds and writes cycle state used by Filter. -func (pl *NodeAffinity) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - affinity := pod.Spec.Affinity - noNodeAffinity := (affinity == nil || - affinity.NodeAffinity == nil || - affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution == nil) - if noNodeAffinity && pl.addedNodeSelector == nil && pod.Spec.NodeSelector == nil { - // NodeAffinity Filter has nothing to do with the Pod. - return nil, framework.NewStatus(framework.Skip) - } - - state := &preFilterState{requiredNodeSelectorAndAffinity: nodeaffinity.GetRequiredNodeAffinity(pod)} - cycleState.Write(preFilterStateKey, state) - - if noNodeAffinity || len(affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms) == 0 { - return nil, nil - } - - // Check if there is affinity to a specific node and return it. - terms := affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms - var nodeNames sets.Set[string] - for _, t := range terms { - var termNodeNames sets.Set[string] - for _, r := range t.MatchFields { - if r.Key == metav1.ObjectNameField && r.Operator == v1.NodeSelectorOpIn { - // The requirements represent ANDed constraints, and so we need to - // find the intersection of nodes. - s := sets.New(r.Values...) - if termNodeNames == nil { - termNodeNames = s - } else { - termNodeNames = termNodeNames.Intersection(s) - } - } - } - if termNodeNames == nil { - // If this term has no node.Name field affinity, - // then all nodes are eligible because the terms are ORed. - return nil, nil - } - nodeNames = nodeNames.Union(termNodeNames) - } - // If nodeNames is not nil, but length is 0, it means each term have conflicting affinity to node.Name; - // therefore, pod will not match any node. - if nodeNames != nil && len(nodeNames) == 0 { - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, errReasonConflict) - } else if len(nodeNames) > 0 { - return &framework.PreFilterResult{NodeNames: nodeNames}, nil - } - return nil, nil - -} - -// PreFilterExtensions not necessary for this plugin as state doesn't depend on pod additions or deletions. -func (pl *NodeAffinity) PreFilterExtensions() framework.PreFilterExtensions { - return nil -} - -// Filter checks if the Node matches the Pod .spec.affinity.nodeAffinity and -// the plugin's added affinity. -func (pl *NodeAffinity) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - node := nodeInfo.Node() - - if pl.addedNodeSelector != nil && !pl.addedNodeSelector.Match(node) { - return framework.NewStatus(framework.UnschedulableAndUnresolvable, errReasonEnforced) - } - - s, err := getPreFilterState(state) - if err != nil { - // Fallback to calculate requiredNodeSelector and requiredNodeAffinity - // here when PreFilter is disabled. - s = &preFilterState{requiredNodeSelectorAndAffinity: nodeaffinity.GetRequiredNodeAffinity(pod)} - } - - // Ignore parsing errors for backwards compatibility. - match, _ := s.requiredNodeSelectorAndAffinity.Match(node) - if !match { - return framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonPod) - } - - return nil -} - -// preScoreState computed at PreScore and used at Score. -type preScoreState struct { - preferredNodeAffinity *nodeaffinity.PreferredSchedulingTerms -} - -// Clone implements the mandatory Clone interface. We don't really copy the data since -// there is no need for that. -func (s *preScoreState) Clone() framework.StateData { - return s -} - -// PreScore builds and writes cycle state used by Score and NormalizeScore. -func (pl *NodeAffinity) PreScore(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) *framework.Status { - preferredNodeAffinity, err := getPodPreferredNodeAffinity(pod) - if err != nil { - return framework.AsStatus(err) - } - if preferredNodeAffinity == nil && pl.addedPrefSchedTerms == nil { - // NodeAffinity Score has nothing to do with the Pod. - return framework.NewStatus(framework.Skip) - } - state := &preScoreState{ - preferredNodeAffinity: preferredNodeAffinity, - } - cycleState.Write(preScoreStateKey, state) - return nil -} - -// Score returns the sum of the weights of the terms that match the Node. -// Terms came from the Pod .spec.affinity.nodeAffinity and from the plugin's -// default affinity. -func (pl *NodeAffinity) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - node := nodeInfo.Node() - - var count int64 - if pl.addedPrefSchedTerms != nil { - count += pl.addedPrefSchedTerms.Score(node) - } - - s, err := getPreScoreState(state) - if err != nil { - // Fallback to calculate preferredNodeAffinity here when PreScore is disabled. - preferredNodeAffinity, err := getPodPreferredNodeAffinity(pod) - if err != nil { - return 0, framework.AsStatus(err) - } - s = &preScoreState{ - preferredNodeAffinity: preferredNodeAffinity, - } - } - - if s.preferredNodeAffinity != nil { - count += s.preferredNodeAffinity.Score(node) - } - - return count, nil -} - -// NormalizeScore invoked after scoring all nodes. -func (pl *NodeAffinity) NormalizeScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status { - return helper.DefaultNormalizeScore(framework.MaxNodeScore, false, scores) -} - -// ScoreExtensions of the Score plugin. -func (pl *NodeAffinity) ScoreExtensions() framework.ScoreExtensions { - return pl -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, plArgs runtime.Object, h framework.Handle, fts feature.Features) (framework.Plugin, error) { - args, err := getArgs(plArgs) - if err != nil { - return nil, err - } - pl := &NodeAffinity{ - handle: h, - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - } - if args.AddedAffinity != nil { - if ns := args.AddedAffinity.RequiredDuringSchedulingIgnoredDuringExecution; ns != nil { - pl.addedNodeSelector, err = nodeaffinity.NewNodeSelector(ns) - if err != nil { - return nil, fmt.Errorf("parsing addedAffinity.requiredDuringSchedulingIgnoredDuringExecution: %w", err) - } - } - // TODO: parse requiredDuringSchedulingRequiredDuringExecution when it gets added to the API. - if terms := args.AddedAffinity.PreferredDuringSchedulingIgnoredDuringExecution; len(terms) != 0 { - pl.addedPrefSchedTerms, err = nodeaffinity.NewPreferredSchedulingTerms(terms) - if err != nil { - return nil, fmt.Errorf("parsing addedAffinity.preferredDuringSchedulingIgnoredDuringExecution: %w", err) - } - } - } - return pl, nil -} - -func getArgs(obj runtime.Object) (config.NodeAffinityArgs, error) { - ptr, ok := obj.(*config.NodeAffinityArgs) - if !ok { - return config.NodeAffinityArgs{}, fmt.Errorf("args are not of type NodeAffinityArgs, got %T", obj) - } - return *ptr, validation.ValidateNodeAffinityArgs(nil, ptr) -} - -func getPodPreferredNodeAffinity(pod *v1.Pod) (*nodeaffinity.PreferredSchedulingTerms, error) { - affinity := pod.Spec.Affinity - if affinity != nil && affinity.NodeAffinity != nil && affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution != nil { - return nodeaffinity.NewPreferredSchedulingTerms(affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution) - } - return nil, nil -} - -func getPreScoreState(cycleState *framework.CycleState) (*preScoreState, error) { - c, err := cycleState.Read(preScoreStateKey) - if err != nil { - return nil, fmt.Errorf("reading %q from cycleState: %w", preScoreStateKey, err) - } - - s, ok := c.(*preScoreState) - if !ok { - return nil, fmt.Errorf("invalid PreScore state, got type %T", c) - } - return s, nil -} - -func getPreFilterState(cycleState *framework.CycleState) (*preFilterState, error) { - c, err := cycleState.Read(preFilterStateKey) - if err != nil { - return nil, fmt.Errorf("reading %q from cycleState: %v", preFilterStateKey, err) - } - - s, ok := c.(*preFilterState) - if !ok { - return nil, fmt.Errorf("invalid PreFilter state, got type %T", c) - } - return s, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename/node_name.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename/node_name.go deleted file mode 100644 index 29605a464..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename/node_name.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package nodename - -import ( - "context" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" -) - -// NodeName is a plugin that checks if a pod spec node name matches the current node. -type NodeName struct { - enableSchedulingQueueHint bool -} - -var _ framework.FilterPlugin = &NodeName{} -var _ framework.EnqueueExtensions = &NodeName{} - -const ( - // Name is the name of the plugin used in the plugin registry and configurations. - Name = names.NodeName - - // ErrReason returned when node name doesn't match. - ErrReason = "node(s) didn't match the requested node name" -) - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *NodeName) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // A note about UpdateNodeTaint/UpdateNodeLabel event: - // Ideally, it's supposed to register only Add because any Node update event will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeTaint | framework.UpdateNodeLabel - if pl.enableSchedulingQueueHint { - // preCheck is not used when QHint is enabled, and hence Update event isn't necessary. - nodeActionType = framework.Add - } - - return []framework.ClusterEventWithHint{ - // We don't need the QueueingHintFn here because the scheduling of Pods will be always retried with backoff when this Event happens. - // (the same as Queue) - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}}, - }, nil -} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *NodeName) Name() string { - return Name -} - -// Filter invoked at the filter extension point. -func (pl *NodeName) Filter(ctx context.Context, _ *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - - if !Fits(pod, nodeInfo) { - return framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReason) - } - return nil -} - -// Fits actually checks if the pod fits the node. -func Fits(pod *v1.Pod, nodeInfo *framework.NodeInfo) bool { - return len(pod.Spec.NodeName) == 0 || pod.Spec.NodeName == nodeInfo.Node().Name -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, _ framework.Handle, fts feature.Features) (framework.Plugin, error) { - return &NodeName{ - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - }, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports/node_ports.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports/node_ports.go deleted file mode 100644 index 37b274a3f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports/node_ports.go +++ /dev/null @@ -1,191 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package nodeports - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// NodePorts is a plugin that checks if a node has free ports for the requested pod ports. -type NodePorts struct { - enableSchedulingQueueHint bool -} - -var _ framework.PreFilterPlugin = &NodePorts{} -var _ framework.FilterPlugin = &NodePorts{} -var _ framework.EnqueueExtensions = &NodePorts{} - -const ( - // Name is the name of the plugin used in the plugin registry and configurations. - Name = names.NodePorts - - // preFilterStateKey is the key in CycleState to NodePorts pre-computed data. - // Using the name of the plugin will likely help us avoid collisions with other plugins. - preFilterStateKey = "PreFilter" + Name - - // ErrReason when node ports aren't available. - ErrReason = "node(s) didn't have free ports for the requested pod ports" -) - -type preFilterState []v1.ContainerPort - -// Clone the prefilter state.getContainerPorts(pod) -func (s preFilterState) Clone() framework.StateData { - // The state is not impacted by adding/removing existing pods, hence we don't need to make a deep copy. - return s -} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *NodePorts) Name() string { - return Name -} - -// PreFilter invoked at the prefilter extension point. -func (pl *NodePorts) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - s := util.GetHostPorts(pod) - // Skip if a pod has no ports. - if len(s) == 0 { - return nil, framework.NewStatus(framework.Skip) - } - cycleState.Write(preFilterStateKey, preFilterState(s)) - return nil, nil -} - -// PreFilterExtensions do not exist for this plugin. -func (pl *NodePorts) PreFilterExtensions() framework.PreFilterExtensions { - return nil -} - -func getPreFilterState(cycleState *framework.CycleState) (preFilterState, error) { - c, err := cycleState.Read(preFilterStateKey) - if err != nil { - // preFilterState doesn't exist, likely PreFilter wasn't invoked. - return nil, fmt.Errorf("reading %q from cycleState: %w", preFilterStateKey, err) - } - - s, ok := c.(preFilterState) - if !ok { - return nil, fmt.Errorf("%+v convert to nodeports.preFilterState error", c) - } - return s, nil -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *NodePorts) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // A note about UpdateNodeTaint/UpdateNodeLabel event: - // Ideally, it's supposed to register only Add because NodeUpdated event never means to have any free ports for the Pod. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeTaint | framework.UpdateNodeLabel - if pl.enableSchedulingQueueHint { - // preCheck is not used when QHint is enabled, and hence Update event isn't necessary. - nodeActionType = framework.Add - } - - return []framework.ClusterEventWithHint{ - // Due to immutable fields `spec.containers[*].ports`, pod update events are ignored. - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.Delete}, QueueingHintFn: pl.isSchedulableAfterPodDeleted}, - // We don't need the QueueingHintFn here because the scheduling of Pods will be always retried with backoff when this Event happens. - // (the same as Queue) - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}}, - }, nil -} - -// isSchedulableAfterPodDeleted is invoked whenever a pod deleted. It checks whether -// that change made a previously unschedulable pod schedulable. -func (pl *NodePorts) isSchedulableAfterPodDeleted(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - deletedPod, _, err := util.As[*v1.Pod](oldObj, nil) - if err != nil { - return framework.Queue, err - } - - // If the deleted pod is unscheduled, it doesn't make the target pod schedulable. - if deletedPod.Spec.NodeName == "" && deletedPod.Status.NominatedNodeName == "" { - logger.V(4).Info("the deleted pod is unscheduled and it doesn't make the target pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(deletedPod)) - return framework.QueueSkip, nil - } - - // If the deleted pod doesn't use any host ports, it doesn't make the target pod schedulable. - ports := util.GetHostPorts(deletedPod) - if len(ports) == 0 { - return framework.QueueSkip, nil - } - - // Construct a fake NodeInfo that only has the deleted Pod. - // If we can schedule `pod` to this fake node, it means that `pod` and the deleted pod don't have any common port(s). - // So, deleting that pod couldn't make `pod` schedulable. - usedPorts := make(framework.HostPortInfo, len(ports)) - for _, p := range ports { - usedPorts.Add(p.HostIP, string(p.Protocol), p.HostPort) - } - nodeInfo := framework.NodeInfo{UsedPorts: usedPorts} - if Fits(pod, &nodeInfo) { - logger.V(4).Info("the deleted pod and the target pod don't have any common port(s), returning QueueSkip as deleting this Pod won't make the Pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(deletedPod)) - return framework.QueueSkip, nil - } - - logger.V(4).Info("the deleted pod and the target pod have any common port(s), returning Queue as deleting this Pod may make the Pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(deletedPod)) - return framework.Queue, nil -} - -// Filter invoked at the filter extension point. -func (pl *NodePorts) Filter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - wantPorts, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - - fits := fitsPorts(wantPorts, nodeInfo) - if !fits { - return framework.NewStatus(framework.Unschedulable, ErrReason) - } - - return nil -} - -// Fits checks if the pod fits the node. -func Fits(pod *v1.Pod, nodeInfo *framework.NodeInfo) bool { - return fitsPorts(util.GetHostPorts(pod), nodeInfo) -} - -func fitsPorts(wantPorts []v1.ContainerPort, nodeInfo *framework.NodeInfo) bool { - // try to see whether existingPorts and wantPorts will conflict or not - existingPorts := nodeInfo.UsedPorts - for _, cp := range wantPorts { - if existingPorts.CheckConflict(cp.HostIP, string(cp.Protocol), cp.HostPort) { - return false - } - } - return true -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, _ framework.Handle, fts feature.Features) (framework.Plugin, error) { - return &NodePorts{ - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - }, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go deleted file mode 100644 index 30c31f14e..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/balanced_allocation.go +++ /dev/null @@ -1,179 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package noderesources - -import ( - "context" - "fmt" - "math" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" -) - -// BalancedAllocation is a score plugin that calculates the difference between the cpu and memory fraction -// of capacity, and prioritizes the host based on how close the two metrics are to each other. -type BalancedAllocation struct { - handle framework.Handle - resourceAllocationScorer -} - -var _ framework.PreScorePlugin = &BalancedAllocation{} -var _ framework.ScorePlugin = &BalancedAllocation{} - -// BalancedAllocationName is the name of the plugin used in the plugin registry and configurations. -const ( - BalancedAllocationName = names.NodeResourcesBalancedAllocation - - // balancedAllocationPreScoreStateKey is the key in CycleState to NodeResourcesBalancedAllocation pre-computed data for Scoring. - balancedAllocationPreScoreStateKey = "PreScore" + BalancedAllocationName -) - -// balancedAllocationPreScoreState computed at PreScore and used at Score. -type balancedAllocationPreScoreState struct { - // podRequests have the same order of the resources defined in NodeResourcesFitArgs.Resources, - // same for other place we store a list like that. - podRequests []int64 -} - -// Clone implements the mandatory Clone interface. We don't really copy the data since -// there is no need for that. -func (s *balancedAllocationPreScoreState) Clone() framework.StateData { - return s -} - -// PreScore calculates incoming pod's resource requests and writes them to the cycle state used. -func (ba *BalancedAllocation) PreScore(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) *framework.Status { - podRequests := ba.calculatePodResourceRequestList(pod, ba.resources) - if ba.isBestEffortPod(podRequests) { - // Skip BalancedAllocation scoring for best-effort pods to - // prevent a large number of pods from being scheduled to the same node. - // See https://github.com/kubernetes/kubernetes/issues/129138 for details. - return framework.NewStatus(framework.Skip) - } - state := &balancedAllocationPreScoreState{ - podRequests: podRequests, - } - cycleState.Write(balancedAllocationPreScoreStateKey, state) - return nil -} - -func getBalancedAllocationPreScoreState(cycleState *framework.CycleState) (*balancedAllocationPreScoreState, error) { - c, err := cycleState.Read(balancedAllocationPreScoreStateKey) - if err != nil { - return nil, fmt.Errorf("reading %q from cycleState: %w", balancedAllocationPreScoreStateKey, err) - } - - s, ok := c.(*balancedAllocationPreScoreState) - if !ok { - return nil, fmt.Errorf("invalid PreScore state, got type %T", c) - } - return s, nil -} - -// Name returns name of the plugin. It is used in logs, etc. -func (ba *BalancedAllocation) Name() string { - return BalancedAllocationName -} - -// Score invoked at the score extension point. -func (ba *BalancedAllocation) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - s, err := getBalancedAllocationPreScoreState(state) - if err != nil { - s = &balancedAllocationPreScoreState{podRequests: ba.calculatePodResourceRequestList(pod, ba.resources)} - if ba.isBestEffortPod(s.podRequests) { - return 0, nil - } - } - - // ba.score favors nodes with balanced resource usage rate. - // It calculates the standard deviation for those resources and prioritizes the node based on how close the usage of those resources is to each other. - // Detail: score = (1 - std) * MaxNodeScore, where std is calculated by the root square of Σ((fraction(i)-mean)^2)/len(resources) - // The algorithm is partly inspired by: - // "Wei Huang et al. An Energy Efficient Virtual Machine Placement Algorithm with Balanced Resource Utilization" - return ba.score(ctx, pod, nodeInfo, s.podRequests) -} - -// ScoreExtensions of the Score plugin. -func (ba *BalancedAllocation) ScoreExtensions() framework.ScoreExtensions { - return nil -} - -// NewBalancedAllocation initializes a new plugin and returns it. -func NewBalancedAllocation(_ context.Context, baArgs runtime.Object, h framework.Handle, fts feature.Features) (framework.Plugin, error) { - args, ok := baArgs.(*config.NodeResourcesBalancedAllocationArgs) - if !ok { - return nil, fmt.Errorf("want args to be of type NodeResourcesBalancedAllocationArgs, got %T", baArgs) - } - - if err := validation.ValidateNodeResourcesBalancedAllocationArgs(nil, args); err != nil { - return nil, err - } - - return &BalancedAllocation{ - handle: h, - resourceAllocationScorer: resourceAllocationScorer{ - Name: BalancedAllocationName, - enableInPlacePodVerticalScaling: fts.EnableInPlacePodVerticalScaling, - enablePodLevelResources: fts.EnablePodLevelResources, - scorer: balancedResourceScorer, - useRequested: true, - resources: args.Resources, - }, - }, nil -} - -func balancedResourceScorer(requested, allocable []int64) int64 { - var resourceToFractions []float64 - var totalFraction float64 - for i := range requested { - if allocable[i] == 0 { - continue - } - fraction := float64(requested[i]) / float64(allocable[i]) - if fraction > 1 { - fraction = 1 - } - totalFraction += fraction - resourceToFractions = append(resourceToFractions, fraction) - } - - std := 0.0 - - // For most cases, resources are limited to cpu and memory, the std could be simplified to std := (fraction1-fraction2)/2 - // len(fractions) > 2: calculate std based on the well-known formula - root square of Σ((fraction(i)-mean)^2)/len(fractions) - // Otherwise, set the std to zero is enough. - if len(resourceToFractions) == 2 { - std = math.Abs((resourceToFractions[0] - resourceToFractions[1]) / 2) - } else if len(resourceToFractions) > 2 { - mean := totalFraction / float64(len(resourceToFractions)) - var sum float64 - for _, fraction := range resourceToFractions { - sum = sum + (fraction-mean)*(fraction-mean) - } - std = math.Sqrt(sum / float64(len(resourceToFractions))) - } - - // STD (standard deviation) is always a positive value. 1-deviation lets the score to be higher for node which has least deviation and - // multiplying it with `MaxNodeScore` provides the scaling factor needed. - return int64((1 - std) * float64(framework.MaxNodeScore)) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go deleted file mode 100644 index d94554ad6..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/fit.go +++ /dev/null @@ -1,591 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package noderesources - -import ( - "context" - "fmt" - "strings" - - "github.com/google/go-cmp/cmp" //nolint:depguard - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/component-helpers/resource" - "k8s.io/klog/v2" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - schedutil "k8s.io/kubernetes/pkg/scheduler/util" -) - -var _ framework.PreFilterPlugin = &Fit{} -var _ framework.FilterPlugin = &Fit{} -var _ framework.EnqueueExtensions = &Fit{} -var _ framework.PreScorePlugin = &Fit{} -var _ framework.ScorePlugin = &Fit{} - -const ( - // Name is the name of the plugin used in the plugin registry and configurations. - Name = names.NodeResourcesFit - - // preFilterStateKey is the key in CycleState to NodeResourcesFit pre-computed data. - // Using the name of the plugin will likely help us avoid collisions with other plugins. - preFilterStateKey = "PreFilter" + Name - - // preScoreStateKey is the key in CycleState to NodeResourcesFit pre-computed data for Scoring. - preScoreStateKey = "PreScore" + Name -) - -// nodeResourceStrategyTypeMap maps strategy to scorer implementation -var nodeResourceStrategyTypeMap = map[config.ScoringStrategyType]scorer{ - config.LeastAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer { - resources := args.ScoringStrategy.Resources - return &resourceAllocationScorer{ - Name: string(config.LeastAllocated), - scorer: leastResourceScorer(resources), - resources: resources, - } - }, - config.MostAllocated: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer { - resources := args.ScoringStrategy.Resources - return &resourceAllocationScorer{ - Name: string(config.MostAllocated), - scorer: mostResourceScorer(resources), - resources: resources, - } - }, - config.RequestedToCapacityRatio: func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer { - resources := args.ScoringStrategy.Resources - return &resourceAllocationScorer{ - Name: string(config.RequestedToCapacityRatio), - scorer: requestedToCapacityRatioScorer(resources, args.ScoringStrategy.RequestedToCapacityRatio.Shape), - resources: resources, - } - }, -} - -// Fit is a plugin that checks if a node has sufficient resources. -type Fit struct { - ignoredResources sets.Set[string] - ignoredResourceGroups sets.Set[string] - enableInPlacePodVerticalScaling bool - enableSidecarContainers bool - enableSchedulingQueueHint bool - enablePodLevelResources bool - handle framework.Handle - resourceAllocationScorer -} - -// ScoreExtensions of the Score plugin. -func (f *Fit) ScoreExtensions() framework.ScoreExtensions { - return nil -} - -// preFilterState computed at PreFilter and used at Filter. -type preFilterState struct { - framework.Resource -} - -// Clone the prefilter state. -func (s *preFilterState) Clone() framework.StateData { - return s -} - -// preScoreState computed at PreScore and used at Score. -type preScoreState struct { - // podRequests have the same order as the resources defined in NodeResourcesBalancedAllocationArgs.Resources, - // same for other place we store a list like that. - podRequests []int64 -} - -// Clone implements the mandatory Clone interface. We don't really copy the data since -// there is no need for that. -func (s *preScoreState) Clone() framework.StateData { - return s -} - -// PreScore calculates incoming pod's resource requests and writes them to the cycle state used. -func (f *Fit) PreScore(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) *framework.Status { - state := &preScoreState{ - podRequests: f.calculatePodResourceRequestList(pod, f.resources), - } - cycleState.Write(preScoreStateKey, state) - return nil -} - -func getPreScoreState(cycleState *framework.CycleState) (*preScoreState, error) { - c, err := cycleState.Read(preScoreStateKey) - if err != nil { - return nil, fmt.Errorf("reading %q from cycleState: %w", preScoreStateKey, err) - } - - s, ok := c.(*preScoreState) - if !ok { - return nil, fmt.Errorf("invalid PreScore state, got type %T", c) - } - return s, nil -} - -// Name returns name of the plugin. It is used in logs, etc. -func (f *Fit) Name() string { - return Name -} - -// NewFit initializes a new plugin and returns it. -func NewFit(_ context.Context, plArgs runtime.Object, h framework.Handle, fts feature.Features) (framework.Plugin, error) { - args, ok := plArgs.(*config.NodeResourcesFitArgs) - if !ok { - return nil, fmt.Errorf("want args to be of type NodeResourcesFitArgs, got %T", plArgs) - } - if err := validation.ValidateNodeResourcesFitArgs(nil, args); err != nil { - return nil, err - } - - if args.ScoringStrategy == nil { - return nil, fmt.Errorf("scoring strategy not specified") - } - - strategy := args.ScoringStrategy.Type - scorePlugin, exists := nodeResourceStrategyTypeMap[strategy] - if !exists { - return nil, fmt.Errorf("scoring strategy %s is not supported", strategy) - } - - return &Fit{ - ignoredResources: sets.New(args.IgnoredResources...), - ignoredResourceGroups: sets.New(args.IgnoredResourceGroups...), - enableInPlacePodVerticalScaling: fts.EnableInPlacePodVerticalScaling, - enableSidecarContainers: fts.EnableSidecarContainers, - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - handle: h, - enablePodLevelResources: fts.EnablePodLevelResources, - resourceAllocationScorer: *scorePlugin(args), - }, nil -} - -type ResourceRequestsOptions struct { - EnablePodLevelResources bool -} - -// computePodResourceRequest returns a framework.Resource that covers the largest -// width in each resource dimension. Because init-containers run sequentially, we collect -// the max in each dimension iteratively. In contrast, we sum the resource vectors for -// regular containers since they run simultaneously. -// -// # The resources defined for Overhead should be added to the calculated Resource request sum -// -// Example: -// -// Pod: -// -// InitContainers -// IC1: -// CPU: 2 -// Memory: 1G -// IC2: -// CPU: 2 -// Memory: 3G -// Containers -// C1: -// CPU: 2 -// Memory: 1G -// C2: -// CPU: 1 -// Memory: 1G -// -// Result: CPU: 3, Memory: 3G -// TODO(ndixita): modify computePodResourceRequest to accept opts of type -// ResourceRequestOptions as the second parameter. -func computePodResourceRequest(pod *v1.Pod, opts ResourceRequestsOptions) *preFilterState { - // pod hasn't scheduled yet so we don't need to worry about InPlacePodVerticalScalingEnabled - reqs := resource.PodRequests(pod, resource.PodResourcesOptions{ - // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !opts.EnablePodLevelResources, - }) - result := &preFilterState{} - result.SetMaxResource(reqs) - return result -} - -// PreFilter invoked at the prefilter extension point. -func (f *Fit) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - if !f.enableSidecarContainers && hasRestartableInitContainer(pod) { - // Scheduler will calculate resources usage for a Pod containing - // restartable init containers that will be equal or more than kubelet will - // require to run the Pod. So there will be no overbooking. However, to - // avoid the inconsistency in resource calculation between the scheduler - // and the older (before v1.28) kubelet, make the Pod unschedulable. - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, "Pod has a restartable init container and the SidecarContainers feature is disabled") - } - cycleState.Write(preFilterStateKey, computePodResourceRequest(pod, ResourceRequestsOptions{EnablePodLevelResources: f.enablePodLevelResources})) - return nil, nil -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (f *Fit) PreFilterExtensions() framework.PreFilterExtensions { - return nil -} - -func getPreFilterState(cycleState *framework.CycleState) (*preFilterState, error) { - c, err := cycleState.Read(preFilterStateKey) - if err != nil { - // preFilterState doesn't exist, likely PreFilter wasn't invoked. - return nil, fmt.Errorf("error reading %q from cycleState: %w", preFilterStateKey, err) - } - - s, ok := c.(*preFilterState) - if !ok { - return nil, fmt.Errorf("%+v convert to NodeResourcesFit.preFilterState error", c) - } - return s, nil -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (f *Fit) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - podActionType := framework.Delete - if f.enableInPlacePodVerticalScaling { - // If InPlacePodVerticalScaling (KEP 1287) is enabled, then UpdatePodScaleDown event should be registered - // for this plugin since a Pod update may free up resources that make other Pods schedulable. - podActionType |= framework.UpdatePodScaleDown - } - - // A note about UpdateNodeTaint/UpdateNodeLabel event: - // Ideally, it's supposed to register only Add | UpdateNodeAllocatable because the only resource update could change the node resource fit plugin's result. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeAllocatable | framework.UpdateNodeTaint | framework.UpdateNodeLabel - if f.enableSchedulingQueueHint { - // preCheck is not used when QHint is enabled, and hence Update event isn't necessary. - nodeActionType = framework.Add | framework.UpdateNodeAllocatable - } - - return []framework.ClusterEventWithHint{ - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: podActionType}, QueueingHintFn: f.isSchedulableAfterPodEvent}, - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}, QueueingHintFn: f.isSchedulableAfterNodeChange}, - }, nil -} - -// isSchedulableAfterPodEvent is invoked whenever a pod deleted or scaled down. It checks whether -// that change made a previously unschedulable pod schedulable. -func (f *Fit) isSchedulableAfterPodEvent(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalPod, modifiedPod, err := schedutil.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - if modifiedPod == nil { - if originalPod.Spec.NodeName == "" && originalPod.Status.NominatedNodeName == "" { - logger.V(5).Info("the deleted pod was unscheduled and it wouldn't make the unscheduled pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(originalPod)) - return framework.QueueSkip, nil - } - - // any deletion event to a scheduled pod could make the unscheduled pod schedulable. - logger.V(5).Info("another scheduled pod was deleted, and it may make the unscheduled pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(originalPod)) - return framework.Queue, nil - } - - if !f.enableInPlacePodVerticalScaling { - // If InPlacePodVerticalScaling (KEP 1287) is disabled, the pod scale down event cannot free up any resources. - logger.V(5).Info("another pod was modified, but InPlacePodVerticalScaling is disabled, so it doesn't make the unscheduled pod schedulable", "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - if !f.isSchedulableAfterPodScaleDown(pod, originalPod, modifiedPod) { - if loggerV := logger.V(10); loggerV.Enabled() { - // Log more information. - loggerV.Info("pod got scaled down, but the modification isn't related to the resource requests of the target pod", "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod), "diff", cmp.Diff(originalPod, modifiedPod)) - } else { - logger.V(5).Info("pod got scaled down, but the modification isn't related to the resource requests of the target pod", "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - } - return framework.QueueSkip, nil - } - - logger.V(5).Info("another scheduled pod or the target pod itself got scaled down, and it may make the unscheduled pod schedulable", "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.Queue, nil -} - -// isSchedulableAfterPodScaleDown checks whether the scale down event may make the target pod schedulable. Specifically: -// - Returns true when the update event is for the target pod itself. -// - Returns true when the update event shows a scheduled pod's resource request that the target pod also requests got reduced. -func (f *Fit) isSchedulableAfterPodScaleDown(targetPod, originalPod, modifiedPod *v1.Pod) bool { - if modifiedPod.UID == targetPod.UID { - // If the scaling down event is for targetPod, it would make targetPod schedulable. - return true - } - - if modifiedPod.Spec.NodeName == "" { - // If the update event is for a unscheduled Pod, - // it wouldn't make targetPod schedulable. - return false - } - - // the other pod was scheduled, so modification or deletion may free up some resources. - originalMaxResourceReq, modifiedMaxResourceReq := &framework.Resource{}, &framework.Resource{} - originalMaxResourceReq.SetMaxResource(resource.PodRequests(originalPod, resource.PodResourcesOptions{UseStatusResources: f.enableInPlacePodVerticalScaling})) - modifiedMaxResourceReq.SetMaxResource(resource.PodRequests(modifiedPod, resource.PodResourcesOptions{UseStatusResources: f.enableInPlacePodVerticalScaling})) - - // check whether the resource request of the modified pod is less than the original pod. - podRequests := resource.PodRequests(targetPod, resource.PodResourcesOptions{UseStatusResources: f.enableInPlacePodVerticalScaling}) - for rName, rValue := range podRequests { - if rValue.IsZero() { - // We only care about the resources requested by the pod we are trying to schedule. - continue - } - switch rName { - case v1.ResourceCPU: - if originalMaxResourceReq.MilliCPU > modifiedMaxResourceReq.MilliCPU { - return true - } - case v1.ResourceMemory: - if originalMaxResourceReq.Memory > modifiedMaxResourceReq.Memory { - return true - } - case v1.ResourceEphemeralStorage: - if originalMaxResourceReq.EphemeralStorage > modifiedMaxResourceReq.EphemeralStorage { - return true - } - default: - if schedutil.IsScalarResourceName(rName) && originalMaxResourceReq.ScalarResources[rName] > modifiedMaxResourceReq.ScalarResources[rName] { - return true - } - } - } - return false -} - -// isSchedulableAfterNodeChange is invoked whenever a node added or changed. It checks whether -// that change could make a previously unschedulable pod schedulable. -func (f *Fit) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalNode, modifiedNode, err := schedutil.As[*v1.Node](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - // Leaving in the queue, since the pod won't fit into the modified node anyway. - if !isFit(pod, modifiedNode, ResourceRequestsOptions{EnablePodLevelResources: f.enablePodLevelResources}) { - logger.V(5).Info("node was created or updated, but it doesn't have enough resource(s) to accommodate this pod", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil - } - // The pod will fit, so since it's add, unblock scheduling. - if originalNode == nil { - logger.V(5).Info("node was added and it might fit the pod's resource requests", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - // The pod will fit, but since there was no increase in available resources, the change won't make the pod schedulable. - if !haveAnyRequestedResourcesIncreased(pod, originalNode, modifiedNode, ResourceRequestsOptions{EnablePodLevelResources: f.enablePodLevelResources}) { - logger.V(5).Info("node was updated, but haven't changed the pod's resource requestments fit assessment", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil - } - - logger.V(5).Info("node was updated, and may now fit the pod's resource requests", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil -} - -// haveAnyRequestedResourcesIncreased returns true if any of the resources requested by the pod have increased or if allowed pod number increased. -func haveAnyRequestedResourcesIncreased(pod *v1.Pod, originalNode, modifiedNode *v1.Node, opts ResourceRequestsOptions) bool { - podRequest := computePodResourceRequest(pod, opts) - originalNodeInfo := framework.NewNodeInfo() - originalNodeInfo.SetNode(originalNode) - modifiedNodeInfo := framework.NewNodeInfo() - modifiedNodeInfo.SetNode(modifiedNode) - - if modifiedNodeInfo.Allocatable.AllowedPodNumber > originalNodeInfo.Allocatable.AllowedPodNumber { - return true - } - - if podRequest.MilliCPU == 0 && - podRequest.Memory == 0 && - podRequest.EphemeralStorage == 0 && - len(podRequest.ScalarResources) == 0 { - return false - } - - if (podRequest.MilliCPU > 0 && modifiedNodeInfo.Allocatable.MilliCPU > originalNodeInfo.Allocatable.MilliCPU) || - (podRequest.Memory > 0 && modifiedNodeInfo.Allocatable.Memory > originalNodeInfo.Allocatable.Memory) || - (podRequest.EphemeralStorage > 0 && modifiedNodeInfo.Allocatable.EphemeralStorage > originalNodeInfo.Allocatable.EphemeralStorage) { - return true - } - - for rName, rQuant := range podRequest.ScalarResources { - // Skip in case request quantity is zero - if rQuant == 0 { - continue - } - - if modifiedNodeInfo.Allocatable.ScalarResources[rName] > originalNodeInfo.Allocatable.ScalarResources[rName] { - return true - } - } - return false -} - -// isFit checks if the pod fits the node. If the node is nil, it returns false. -// It constructs a fake NodeInfo object for the node and checks if the pod fits the node. -func isFit(pod *v1.Pod, node *v1.Node, opts ResourceRequestsOptions) bool { - if node == nil { - return false - } - nodeInfo := framework.NewNodeInfo() - nodeInfo.SetNode(node) - return len(Fits(pod, nodeInfo, opts)) == 0 -} - -// Filter invoked at the filter extension point. -// Checks if a node has sufficient resources, such as cpu, memory, gpu, opaque int resources etc to run a pod. -// It returns a list of insufficient resources, if empty, then the node has all the resources requested by the pod. -func (f *Fit) Filter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - s, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - - insufficientResources := fitsRequest(s, nodeInfo, f.ignoredResources, f.ignoredResourceGroups) - - if len(insufficientResources) != 0 { - // We will keep all failure reasons. - failureReasons := make([]string, 0, len(insufficientResources)) - for i := range insufficientResources { - failureReasons = append(failureReasons, insufficientResources[i].Reason) - } - return framework.NewStatus(framework.Unschedulable, failureReasons...) - } - return nil -} - -func hasRestartableInitContainer(pod *v1.Pod) bool { - for _, c := range pod.Spec.InitContainers { - if c.RestartPolicy != nil && *c.RestartPolicy == v1.ContainerRestartPolicyAlways { - return true - } - } - return false -} - -// InsufficientResource describes what kind of resource limit is hit and caused the pod to not fit the node. -type InsufficientResource struct { - ResourceName v1.ResourceName - // We explicitly have a parameter for reason to avoid formatting a message on the fly - // for common resources, which is expensive for cluster autoscaler simulations. - Reason string - Requested int64 - Used int64 - Capacity int64 -} - -// Fits checks if node have enough resources to host the pod. -func Fits(pod *v1.Pod, nodeInfo *framework.NodeInfo, opts ResourceRequestsOptions) []InsufficientResource { - return fitsRequest(computePodResourceRequest(pod, opts), nodeInfo, nil, nil) -} - -func fitsRequest(podRequest *preFilterState, nodeInfo *framework.NodeInfo, ignoredExtendedResources, ignoredResourceGroups sets.Set[string]) []InsufficientResource { - insufficientResources := make([]InsufficientResource, 0, 4) - - allowedPodNumber := nodeInfo.Allocatable.AllowedPodNumber - if len(nodeInfo.Pods)+1 > allowedPodNumber { - insufficientResources = append(insufficientResources, InsufficientResource{ - ResourceName: v1.ResourcePods, - Reason: "Too many pods", - Requested: 1, - Used: int64(len(nodeInfo.Pods)), - Capacity: int64(allowedPodNumber), - }) - } - - if podRequest.MilliCPU == 0 && - podRequest.Memory == 0 && - podRequest.EphemeralStorage == 0 && - len(podRequest.ScalarResources) == 0 { - return insufficientResources - } - - if podRequest.MilliCPU > 0 && podRequest.MilliCPU > (nodeInfo.Allocatable.MilliCPU-nodeInfo.Requested.MilliCPU) { - insufficientResources = append(insufficientResources, InsufficientResource{ - ResourceName: v1.ResourceCPU, - Reason: "Insufficient cpu", - Requested: podRequest.MilliCPU, - Used: nodeInfo.Requested.MilliCPU, - Capacity: nodeInfo.Allocatable.MilliCPU, - }) - } - if podRequest.Memory > 0 && podRequest.Memory > (nodeInfo.Allocatable.Memory-nodeInfo.Requested.Memory) { - insufficientResources = append(insufficientResources, InsufficientResource{ - ResourceName: v1.ResourceMemory, - Reason: "Insufficient memory", - Requested: podRequest.Memory, - Used: nodeInfo.Requested.Memory, - Capacity: nodeInfo.Allocatable.Memory, - }) - } - if podRequest.EphemeralStorage > 0 && - podRequest.EphemeralStorage > (nodeInfo.Allocatable.EphemeralStorage-nodeInfo.Requested.EphemeralStorage) { - insufficientResources = append(insufficientResources, InsufficientResource{ - ResourceName: v1.ResourceEphemeralStorage, - Reason: "Insufficient ephemeral-storage", - Requested: podRequest.EphemeralStorage, - Used: nodeInfo.Requested.EphemeralStorage, - Capacity: nodeInfo.Allocatable.EphemeralStorage, - }) - } - - for rName, rQuant := range podRequest.ScalarResources { - // Skip in case request quantity is zero - if rQuant == 0 { - continue - } - - if v1helper.IsExtendedResourceName(rName) { - // If this resource is one of the extended resources that should be ignored, we will skip checking it. - // rName is guaranteed to have a slash due to API validation. - var rNamePrefix string - if ignoredResourceGroups.Len() > 0 { - rNamePrefix = strings.Split(string(rName), "/")[0] - } - if ignoredExtendedResources.Has(string(rName)) || ignoredResourceGroups.Has(rNamePrefix) { - continue - } - } - - if rQuant > (nodeInfo.Allocatable.ScalarResources[rName] - nodeInfo.Requested.ScalarResources[rName]) { - insufficientResources = append(insufficientResources, InsufficientResource{ - ResourceName: rName, - Reason: fmt.Sprintf("Insufficient %v", rName), - Requested: podRequest.ScalarResources[rName], - Used: nodeInfo.Requested.ScalarResources[rName], - Capacity: nodeInfo.Allocatable.ScalarResources[rName], - }) - } - } - - return insufficientResources -} - -// Score invoked at the Score extension point. -func (f *Fit) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - s, err := getPreScoreState(state) - if err != nil { - s = &preScoreState{ - podRequests: f.calculatePodResourceRequestList(pod, f.resources), - } - } - - return f.score(ctx, pod, nodeInfo, s.podRequests) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go deleted file mode 100644 index a19969e90..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/least_allocated.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package noderesources - -import ( - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// leastResourceScorer favors nodes with fewer requested resources. -// It calculates the percentage of memory, CPU and other resources requested by pods scheduled on the node, and -// prioritizes based on the minimum of the average of the fraction of requested to capacity. -// -// Details: -// (cpu((capacity-requested)*MaxNodeScore*cpuWeight/capacity) + memory((capacity-requested)*MaxNodeScore*memoryWeight/capacity) + ...)/weightSum -func leastResourceScorer(resources []config.ResourceSpec) func([]int64, []int64) int64 { - return func(requested, allocable []int64) int64 { - var nodeScore, weightSum int64 - for i := range requested { - if allocable[i] == 0 { - continue - } - weight := resources[i].Weight - resourceScore := leastRequestedScore(requested[i], allocable[i]) - nodeScore += resourceScore * weight - weightSum += weight - } - if weightSum == 0 { - return 0 - } - return nodeScore / weightSum - } -} - -// The unused capacity is calculated on a scale of 0-MaxNodeScore -// 0 being the lowest priority and `MaxNodeScore` being the highest. -// The more unused resources the higher the score is. -func leastRequestedScore(requested, capacity int64) int64 { - if capacity == 0 { - return 0 - } - if requested > capacity { - return 0 - } - - return ((capacity - requested) * framework.MaxNodeScore) / capacity -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go deleted file mode 100644 index 414256988..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/most_allocated.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package noderesources - -import ( - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// mostResourceScorer favors nodes with most requested resources. -// It calculates the percentage of memory and CPU requested by pods scheduled on the node, and prioritizes -// based on the maximum of the average of the fraction of requested to capacity. -// -// Details: -// (cpu(MaxNodeScore * requested * cpuWeight / capacity) + memory(MaxNodeScore * requested * memoryWeight / capacity) + ...) / weightSum -func mostResourceScorer(resources []config.ResourceSpec) func(requested, allocable []int64) int64 { - return func(requested, allocable []int64) int64 { - var nodeScore, weightSum int64 - for i := range requested { - if allocable[i] == 0 { - continue - } - weight := resources[i].Weight - resourceScore := mostRequestedScore(requested[i], allocable[i]) - nodeScore += resourceScore * weight - weightSum += weight - } - if weightSum == 0 { - return 0 - } - return nodeScore / weightSum - } -} - -// The used capacity is calculated on a scale of 0-MaxNodeScore (MaxNodeScore is -// constant with value set to 100). -// 0 being the lowest priority and 100 being the highest. -// The more resources are used the higher the score is. This function -// is almost a reversed version of noderesources.leastRequestedScore. -func mostRequestedScore(requested, capacity int64) int64 { - if capacity == 0 { - return 0 - } - if requested > capacity { - // `requested` might be greater than `capacity` because pods with no - // requests get minimum values. - requested = capacity - } - - return (requested * framework.MaxNodeScore) / capacity -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go deleted file mode 100644 index df5e2ff47..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/requested_to_capacity_ratio.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package noderesources - -import ( - "math" - - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" -) - -const maxUtilization = 100 - -// buildRequestedToCapacityRatioScorerFunction allows users to apply bin packing -// on core resources like CPU, Memory as well as extended resources like accelerators. -func buildRequestedToCapacityRatioScorerFunction(scoringFunctionShape helper.FunctionShape, resources []config.ResourceSpec) func([]int64, []int64) int64 { - rawScoringFunction := helper.BuildBrokenLinearFunction(scoringFunctionShape) - resourceScoringFunction := func(requested, capacity int64) int64 { - if capacity == 0 || requested > capacity { - return rawScoringFunction(maxUtilization) - } - - return rawScoringFunction(requested * maxUtilization / capacity) - } - return func(requested, allocable []int64) int64 { - var nodeScore, weightSum int64 - for i := range requested { - if allocable[i] == 0 { - continue - } - weight := resources[i].Weight - resourceScore := resourceScoringFunction(requested[i], allocable[i]) - if resourceScore > 0 { - nodeScore += resourceScore * weight - weightSum += weight - } - } - if weightSum == 0 { - return 0 - } - return int64(math.Round(float64(nodeScore) / float64(weightSum))) - } -} - -func requestedToCapacityRatioScorer(resources []config.ResourceSpec, shape []config.UtilizationShapePoint) func([]int64, []int64) int64 { - shapes := make([]helper.FunctionShapePoint, 0, len(shape)) - for _, point := range shape { - shapes = append(shapes, helper.FunctionShapePoint{ - Utilization: int64(point.Utilization), - // MaxCustomPriorityScore may diverge from the max score used in the scheduler and defined by MaxNodeScore, - // therefore we need to scale the score returned by requested to capacity ratio to the score range - // used by the scheduler. - Score: int64(point.Score) * (framework.MaxNodeScore / config.MaxCustomPriorityScore), - }) - } - - return buildRequestedToCapacityRatioScorerFunction(shapes, resources) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go deleted file mode 100644 index 71eb9138b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/resource_allocation.go +++ /dev/null @@ -1,157 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package noderesources - -import ( - "context" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/klog/v2" - - resourcehelper "k8s.io/component-helpers/resource" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework" - schedutil "k8s.io/kubernetes/pkg/scheduler/util" -) - -// scorer is decorator for resourceAllocationScorer -type scorer func(args *config.NodeResourcesFitArgs) *resourceAllocationScorer - -// resourceAllocationScorer contains information to calculate resource allocation score. -type resourceAllocationScorer struct { - Name string - enableInPlacePodVerticalScaling bool - enablePodLevelResources bool - // used to decide whether to use Requested or NonZeroRequested for - // cpu and memory. - useRequested bool - scorer func(requested, allocable []int64) int64 - resources []config.ResourceSpec -} - -// score will use `scorer` function to calculate the score. -func (r *resourceAllocationScorer) score( - ctx context.Context, - pod *v1.Pod, - nodeInfo *framework.NodeInfo, - podRequests []int64) (int64, *framework.Status) { - logger := klog.FromContext(ctx) - node := nodeInfo.Node() - - // resources not set, nothing scheduled, - if len(r.resources) == 0 { - return 0, framework.NewStatus(framework.Error, "resources not found") - } - - requested := make([]int64, len(r.resources)) - allocatable := make([]int64, len(r.resources)) - for i := range r.resources { - alloc, req := r.calculateResourceAllocatableRequest(logger, nodeInfo, v1.ResourceName(r.resources[i].Name), podRequests[i]) - // Only fill the extended resource entry when it's non-zero. - if alloc == 0 { - continue - } - allocatable[i] = alloc - requested[i] = req - } - - score := r.scorer(requested, allocatable) - - if loggerV := logger.V(10); loggerV.Enabled() { // Serializing these maps is costly. - loggerV.Info("Listed internal info for allocatable resources, requested resources and score", "pod", - klog.KObj(pod), "node", klog.KObj(node), "resourceAllocationScorer", r.Name, - "allocatableResource", allocatable, "requestedResource", requested, "resourceScore", score, - ) - } - - return score, nil -} - -// calculateResourceAllocatableRequest returns 2 parameters: -// - 1st param: quantity of allocatable resource on the node. -// - 2nd param: aggregated quantity of requested resource on the node. -// Note: if it's an extended resource, and the pod doesn't request it, (0, 0) is returned. -func (r *resourceAllocationScorer) calculateResourceAllocatableRequest(logger klog.Logger, nodeInfo *framework.NodeInfo, resource v1.ResourceName, podRequest int64) (int64, int64) { - requested := nodeInfo.NonZeroRequested - if r.useRequested { - requested = nodeInfo.Requested - } - - // If it's an extended resource, and the pod doesn't request it. We return (0, 0) - // as an implication to bypass scoring on this resource. - if podRequest == 0 && schedutil.IsScalarResourceName(resource) { - return 0, 0 - } - switch resource { - case v1.ResourceCPU: - return nodeInfo.Allocatable.MilliCPU, (requested.MilliCPU + podRequest) - case v1.ResourceMemory: - return nodeInfo.Allocatable.Memory, (requested.Memory + podRequest) - case v1.ResourceEphemeralStorage: - return nodeInfo.Allocatable.EphemeralStorage, (nodeInfo.Requested.EphemeralStorage + podRequest) - default: - if _, exists := nodeInfo.Allocatable.ScalarResources[resource]; exists { - return nodeInfo.Allocatable.ScalarResources[resource], (nodeInfo.Requested.ScalarResources[resource] + podRequest) - } - } - logger.V(10).Info("Requested resource is omitted for node score calculation", "resourceName", resource) - return 0, 0 -} - -// calculatePodResourceRequest returns the total non-zero requests. If Overhead is defined for the pod -// the Overhead is added to the result. -func (r *resourceAllocationScorer) calculatePodResourceRequest(pod *v1.Pod, resourceName v1.ResourceName) int64 { - - opts := resourcehelper.PodResourcesOptions{ - UseStatusResources: r.enableInPlacePodVerticalScaling, - // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !r.enablePodLevelResources, - } - - if !r.useRequested { - opts.NonMissingContainerRequests = v1.ResourceList{ - v1.ResourceCPU: *resource.NewMilliQuantity(schedutil.DefaultMilliCPURequest, resource.DecimalSI), - v1.ResourceMemory: *resource.NewQuantity(schedutil.DefaultMemoryRequest, resource.DecimalSI), - } - } - - requests := resourcehelper.PodRequests(pod, opts) - - quantity := requests[resourceName] - if resourceName == v1.ResourceCPU { - return quantity.MilliValue() - } - return quantity.Value() -} - -func (r *resourceAllocationScorer) calculatePodResourceRequestList(pod *v1.Pod, resources []config.ResourceSpec) []int64 { - podRequests := make([]int64, len(resources)) - for i := range resources { - podRequests[i] = r.calculatePodResourceRequest(pod, v1.ResourceName(resources[i].Name)) - } - return podRequests -} - -func (r *resourceAllocationScorer) isBestEffortPod(podRequests []int64) bool { - for _, request := range podRequests { - if request != 0 { - return false - } - } - return true -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go deleted file mode 100644 index fd4345117..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources/test_util.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package noderesources - -import ( - "github.com/google/go-cmp/cmp/cmpopts" //nolint:depguard - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/validation/field" - "k8s.io/kubernetes/pkg/scheduler/apis/config" -) - -var ( - ignoreBadValueDetail = cmpopts.IgnoreFields(field.Error{}, "BadValue", "Detail") - defaultResources = []config.ResourceSpec{ - {Name: string(v1.ResourceCPU), Weight: 1}, - {Name: string(v1.ResourceMemory), Weight: 1}, - } - extendedRes = "abc.com/xyz" - extendedResourceSet = []config.ResourceSpec{ - {Name: string(v1.ResourceCPU), Weight: 1}, - {Name: string(v1.ResourceMemory), Weight: 1}, - {Name: extendedRes, Weight: 1}, - } -) - -func makeNode(node string, milliCPU, memory int64, extendedResource map[string]int64) *v1.Node { - resourceList := make(map[v1.ResourceName]resource.Quantity) - for res, quantity := range extendedResource { - resourceList[v1.ResourceName(res)] = *resource.NewQuantity(quantity, resource.DecimalSI) - } - resourceList[v1.ResourceCPU] = *resource.NewMilliQuantity(milliCPU, resource.DecimalSI) - resourceList[v1.ResourceMemory] = *resource.NewQuantity(memory, resource.BinarySI) - return &v1.Node{ - ObjectMeta: metav1.ObjectMeta{Name: node}, - Status: v1.NodeStatus{ - Capacity: resourceList, - Allocatable: resourceList, - }, - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable/node_unschedulable.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable/node_unschedulable.go deleted file mode 100644 index 50a4264aa..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable/node_unschedulable.go +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package nodeunschedulable - -import ( - "context" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - v1helper "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// NodeUnschedulable plugin filters nodes that set node.Spec.Unschedulable=true unless -// the pod tolerates {key=node.kubernetes.io/unschedulable, effect:NoSchedule} taint. -type NodeUnschedulable struct { - enableSchedulingQueueHint bool -} - -var _ framework.FilterPlugin = &NodeUnschedulable{} -var _ framework.EnqueueExtensions = &NodeUnschedulable{} - -// Name is the name of the plugin used in the plugin registry and configurations. -const Name = names.NodeUnschedulable - -const ( - // ErrReasonUnknownCondition is used for NodeUnknownCondition predicate error. - ErrReasonUnknownCondition = "node(s) had unknown conditions" - // ErrReasonUnschedulable is used for NodeUnschedulable predicate error. - ErrReasonUnschedulable = "node(s) were unschedulable" -) - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *NodeUnschedulable) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - if !pl.enableSchedulingQueueHint { - return []framework.ClusterEventWithHint{ - // A note about UpdateNodeLabel event: - // Ideally, it's supposed to register only Add | UpdateNodeTaint because UpdateNodeLabel will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.UpdateNodeTaint | framework.UpdateNodeLabel}, QueueingHintFn: pl.isSchedulableAfterNodeChange}, - }, nil - } - - return []framework.ClusterEventWithHint{ - // When QueueingHint is enabled, we don't use preCheck and we don't need to register UpdateNodeLabel event. - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.UpdateNodeTaint}, QueueingHintFn: pl.isSchedulableAfterNodeChange}, - // When the QueueingHint feature is enabled, - // the scheduling queue uses Pod/Update Queueing Hint - // to determine whether a Pod's update makes the Pod schedulable or not. - // https://github.com/kubernetes/kubernetes/pull/122234 - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.UpdatePodToleration}, QueueingHintFn: pl.isSchedulableAfterPodTolerationChange}, - }, nil -} - -// isSchedulableAfterPodTolerationChange is invoked whenever a pod's toleration changed. -func (pl *NodeUnschedulable) isSchedulableAfterPodTolerationChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, modifiedPod, err := util.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - if pod.UID == modifiedPod.UID { - // Note: we don't need to check oldPod tolerations the taint because: - // - Taint can be added, but can't be modified nor removed. - // - If the Pod already has the toleration, it shouldn't have rejected by this plugin in the first place. - // Meaning, here this Pod has been rejected by this plugin, and hence it shouldn't have the toleration yet. - if v1helper.TolerationsTolerateTaint(modifiedPod.Spec.Tolerations, &v1.Taint{ - Key: v1.TaintNodeUnschedulable, - Effect: v1.TaintEffectNoSchedule, - }) { - // This update makes the pod tolerate the unschedulable taint. - logger.V(5).Info("a new toleration is added for the unschedulable Pod, and it may make it schedulable", "pod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - logger.V(5).Info("a new toleration is added for the unschedulable Pod, but it's an unrelated toleration", "pod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - logger.V(5).Info("a new toleration is added for a Pod, but it's an unrelated Pod and wouldn't change the TaintToleration plugin's decision", "pod", klog.KObj(modifiedPod)) - - return framework.QueueSkip, nil -} - -// isSchedulableAfterNodeChange is invoked for all node events reported by -// an informer. It checks whether that change made a previously unschedulable -// pod schedulable. -func (pl *NodeUnschedulable) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalNode, modifiedNode, err := util.As[*v1.Node](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - // We queue this Pod when - - // 1. the node is updated from unschedulable to schedulable. - // 2. the node is added and is schedulable. - if (originalNode != nil && originalNode.Spec.Unschedulable && !modifiedNode.Spec.Unschedulable) || - (originalNode == nil && !modifiedNode.Spec.Unschedulable) { - logger.V(5).Info("node was created or updated, pod may be schedulable now", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - - logger.V(5).Info("node was created or updated, but it doesn't make this pod schedulable", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil -} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *NodeUnschedulable) Name() string { - return Name -} - -// Filter invoked at the filter extension point. -func (pl *NodeUnschedulable) Filter(ctx context.Context, _ *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - node := nodeInfo.Node() - - if !node.Spec.Unschedulable { - return nil - } - - // If pod tolerate unschedulable taint, it's also tolerate `node.Spec.Unschedulable`. - podToleratesUnschedulable := v1helper.TolerationsTolerateTaint(pod.Spec.Tolerations, &v1.Taint{ - Key: v1.TaintNodeUnschedulable, - Effect: v1.TaintEffectNoSchedule, - }) - if !podToleratesUnschedulable { - return framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonUnschedulable) - } - - return nil -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, _ framework.Handle, fts feature.Features) (framework.Plugin, error) { - return &NodeUnschedulable{enableSchedulingQueueHint: fts.EnableSchedulingQueueHint}, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/OWNERS b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/OWNERS deleted file mode 100644 index be3245e85..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - sig-storage-approvers - - cofyc -reviewers: - - sig-storage-reviewers - - cofyc -labels: - - sig/storage diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go deleted file mode 100644 index 1a3f12d03..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/csi.go +++ /dev/null @@ -1,621 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package nodevolumelimits - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/rand" - corelisters "k8s.io/client-go/listers/core/v1" - storagelisters "k8s.io/client-go/listers/storage/v1" - ephemeral "k8s.io/component-helpers/storage/ephemeral" - storagehelpers "k8s.io/component-helpers/storage/volume" - csitrans "k8s.io/csi-translation-lib" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -const ( - // ErrReasonMaxVolumeCountExceeded is used for MaxVolumeCount predicate error. - ErrReasonMaxVolumeCountExceeded = "node(s) exceed max volume count" -) - -// InTreeToCSITranslator contains methods required to check migratable status -// and perform translations from InTree PV's to CSI -type InTreeToCSITranslator interface { - IsPVMigratable(pv *v1.PersistentVolume) bool - IsInlineMigratable(vol *v1.Volume) bool - IsMigratableIntreePluginByName(inTreePluginName string) bool - GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error) - GetCSINameFromInTreeName(pluginName string) (string, error) - TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) - TranslateInTreeInlineVolumeToCSI(logger klog.Logger, volume *v1.Volume, podNamespace string) (*v1.PersistentVolume, error) -} - -// CSILimits is a plugin that checks node volume limits. -type CSILimits struct { - csiNodeLister storagelisters.CSINodeLister - pvLister corelisters.PersistentVolumeLister - pvcLister corelisters.PersistentVolumeClaimLister - scLister storagelisters.StorageClassLister - vaLister storagelisters.VolumeAttachmentLister - - enableCSIMigrationPortworx bool - randomVolumeIDPrefix string - - translator InTreeToCSITranslator -} - -var _ framework.PreFilterPlugin = &CSILimits{} -var _ framework.FilterPlugin = &CSILimits{} -var _ framework.EnqueueExtensions = &CSILimits{} - -// CSIName is the name of the plugin used in the plugin registry and configurations. -const CSIName = names.NodeVolumeLimits - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *CSILimits) Name() string { - return CSIName -} - -// EventsToRegister returns the possible events that may make a Pod. -// failed by this plugin schedulable. -func (pl *CSILimits) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - return []framework.ClusterEventWithHint{ - // We don't register any `QueueingHintFn` intentionally - // because any new CSINode could make pods that were rejected by CSI volumes schedulable. - {Event: framework.ClusterEvent{Resource: framework.CSINode, ActionType: framework.Add}}, - {Event: framework.ClusterEvent{Resource: framework.CSINode, ActionType: framework.Update}, QueueingHintFn: pl.isSchedulableAfterCSINodeUpdated}, - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.Delete}, QueueingHintFn: pl.isSchedulableAfterPodDeleted}, - {Event: framework.ClusterEvent{Resource: framework.PersistentVolumeClaim, ActionType: framework.Add}, QueueingHintFn: pl.isSchedulableAfterPVCAdded}, - {Event: framework.ClusterEvent{Resource: framework.VolumeAttachment, ActionType: framework.Delete}, QueueingHintFn: pl.isSchedulableAfterVolumeAttachmentDeleted}, - }, nil -} - -func (pl *CSILimits) isSchedulableAfterPodDeleted(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - deletedPod, _, err := util.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterPodDeleted: %w", err) - } - - if len(deletedPod.Spec.Volumes) == 0 { - return framework.QueueSkip, nil - } - - if deletedPod.Spec.NodeName == "" && deletedPod.Status.NominatedNodeName == "" { - return framework.QueueSkip, nil - } - - for _, vol := range deletedPod.Spec.Volumes { - if vol.PersistentVolumeClaim != nil || vol.Ephemeral != nil || pl.translator.IsInlineMigratable(&vol) { - return framework.Queue, nil - } - } - - logger.V(5).Info("The deleted pod does not impact the scheduling of the unscheduled pod", "deletedPod", klog.KObj(pod), "pod", klog.KObj(deletedPod)) - return framework.QueueSkip, nil -} - -func (pl *CSILimits) isSchedulableAfterPVCAdded(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, addedPvc, err := util.As[*v1.PersistentVolumeClaim](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterPVCAdded: %w", err) - } - - if addedPvc.Namespace != pod.Namespace { - return framework.QueueSkip, nil - } - - for _, volumes := range pod.Spec.Volumes { - var pvcName string - switch { - case volumes.PersistentVolumeClaim != nil: - pvcName = volumes.PersistentVolumeClaim.ClaimName - case volumes.Ephemeral != nil: - pvcName = ephemeral.VolumeClaimName(pod, &volumes) - default: - // Volume is not using a PVC, ignore - continue - } - - if pvcName == addedPvc.Name { - logger.V(5).Info("PVC that is referred from the pod was created, which might make this pod schedulable", "pod", klog.KObj(pod), "PVC", klog.KObj(addedPvc)) - return framework.Queue, nil - } - } - - logger.V(5).Info("PVC irrelevant to the Pod was created, which doesn't make this pod schedulable", "pod", klog.KObj(pod), "PVC", klog.KObj(addedPvc)) - return framework.QueueSkip, nil -} - -func (pl *CSILimits) isSchedulableAfterVolumeAttachmentDeleted(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - deletedVolumeAttachment, _, err := util.As[*storagev1.VolumeAttachment](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterVolumeAttachmentDeleted: %w", err) - } - - for _, vol := range pod.Spec.Volumes { - // Check if the pod volume uses a PVC - // If it does, return Queue - if vol.PersistentVolumeClaim != nil { - logger.V(5).Info("Pod volume uses PersistentVolumeClaim, which might make this pod schedulable due to VolumeAttachment deletion", "pod", klog.KObj(pod), "volumeAttachment", klog.KObj(deletedVolumeAttachment), "volume", vol.Name) - return framework.Queue, nil - } - - if !pl.translator.IsInlineMigratable(&vol) { - continue - } - - translatedPV, err := pl.translator.TranslateInTreeInlineVolumeToCSI(logger, &vol, pod.Namespace) - if err != nil || translatedPV == nil { - return framework.Queue, fmt.Errorf("converting volume(%s) from inline to csi: %w", vol.Name, err) - } - - if translatedPV.Spec.CSI != nil && deletedVolumeAttachment.Spec.Attacher == translatedPV.Spec.CSI.Driver { - // deleted VolumeAttachment Attacher matches the translated PV CSI driver - logger.V(5).Info("Pod volume is an Inline Migratable volume that matches the CSI driver, which might make this pod schedulable due to VolumeAttachment deletion", - "pod", klog.KObj(pod), "volumeAttachment", klog.KObj(deletedVolumeAttachment), - "volume", vol.Name, "csiDriver", translatedPV.Spec.CSI.Driver, - ) - return framework.Queue, nil - } - } - - logger.V(5).Info("the VolumeAttachment deletion wouldn't make this pod schedulable because the pod has no volume related to a deleted VolumeAttachment", - "pod", klog.KObj(pod), "volumeAttachment", klog.KObj(deletedVolumeAttachment)) - return framework.QueueSkip, nil -} - -func (pl *CSILimits) isSchedulableAfterCSINodeUpdated(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - oldCSINode, newCSINode, err := util.As[*storagev1.CSINode](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterCSINodeUpdated: %w", err) - } - - oldLimits := make(map[string]int32) - for _, d := range oldCSINode.Spec.Drivers { - var count int32 - if d.Allocatable != nil && d.Allocatable.Count != nil { - count = *d.Allocatable.Count - } - oldLimits[d.Name] = count - } - - // Compare new driver limits vs. old. If limit increased, queue pod. - for _, d := range newCSINode.Spec.Drivers { - var oldLimit int32 - if val, exists := oldLimits[d.Name]; exists { - oldLimit = val - } - newLimit := int32(0) - if d.Allocatable != nil && d.Allocatable.Count != nil { - newLimit = *d.Allocatable.Count - } - - if newLimit > oldLimit { - logger.V(5).Info("CSINode driver limit increased, might make this pod schedulable", - "pod", klog.KObj(pod), - "driver", d.Name, - "oldLimit", oldLimit, - "newLimit", newLimit, - ) - return framework.Queue, nil - } - } - - // If no driver limit was increased, skip queueing. - return framework.QueueSkip, nil -} - -// PreFilter invoked at the prefilter extension point -// -// If the pod haven't those types of volumes, we'll skip the Filter phase -func (pl *CSILimits) PreFilter(ctx context.Context, _ *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - volumes := pod.Spec.Volumes - for i := range volumes { - vol := &volumes[i] - if vol.PersistentVolumeClaim != nil || vol.Ephemeral != nil || pl.translator.IsInlineMigratable(vol) { - return nil, nil - } - } - - return nil, framework.NewStatus(framework.Skip) -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (pl *CSILimits) PreFilterExtensions() framework.PreFilterExtensions { - return nil -} - -// Filter invoked at the filter extension point. -func (pl *CSILimits) Filter(ctx context.Context, _ *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - // If the new pod doesn't have any volume attached to it, the predicate will always be true - if len(pod.Spec.Volumes) == 0 { - return nil - } - - node := nodeInfo.Node() - - logger := klog.FromContext(ctx) - - csiNode, err := pl.csiNodeLister.Get(node.Name) - if err != nil { - // TODO: return the error once CSINode is created by default (2 releases) - logger.V(5).Info("Could not get a CSINode object for the node", "node", klog.KObj(node), "err", err) - } - - // Count CSI volumes from the new pod - newVolumes := make(map[string]string) - if err := pl.filterAttachableVolumes(logger, pod, csiNode, true /* new pod */, newVolumes); err != nil { - if apierrors.IsNotFound(err) { - // PVC is not found. This Pod will never be schedulable until PVC is created. - return framework.NewStatus(framework.UnschedulableAndUnresolvable, err.Error()) - } - return framework.AsStatus(err) - } - - // If the pod doesn't have any new CSI volumes, the predicate will always be true - if len(newVolumes) == 0 { - return nil - } - - // If the node doesn't have volume limits, the predicate will always be true - nodeVolumeLimits := getVolumeLimits(csiNode) - if len(nodeVolumeLimits) == 0 { - return nil - } - - // Count CSI volumes from existing pods - attachedVolumes := make(map[string]string) - for _, existingPod := range nodeInfo.Pods { - if err := pl.filterAttachableVolumes(logger, existingPod.Pod, csiNode, false /* existing pod */, attachedVolumes); err != nil { - return framework.AsStatus(err) - } - } - - attachedVolumeCount := map[string]int{} - for volumeUniqueName, driverName := range attachedVolumes { - // Don't count single volume used in multiple pods more than once - delete(newVolumes, volumeUniqueName) - attachedVolumeCount[driverName]++ - } - - // Count CSI volumes from VolumeAttachments - volumeAttachments, err := pl.getNodeVolumeAttachmentInfo(logger, node.Name) - if err != nil { - return framework.AsStatus(err) - } - - for volumeUniqueName, driverName := range volumeAttachments { - // Avoid double-counting volumes already used by existing pods - if _, exists := attachedVolumes[volumeUniqueName]; !exists { - attachedVolumeCount[driverName]++ - } - } - - // Count the new volumes count per driver - newVolumeCount := map[string]int{} - for _, driverName := range newVolumes { - newVolumeCount[driverName]++ - } - - for driverName, count := range newVolumeCount { - maxVolumeLimit, ok := nodeVolumeLimits[driverName] - if ok { - currentVolumeCount := attachedVolumeCount[driverName] - logger.V(5).Info("Found plugin volume limits", "node", node.Name, "driverName", driverName, - "maxLimits", maxVolumeLimit, "currentVolumeCount", currentVolumeCount, "newVolumeCount", count, - "pod", klog.KObj(pod)) - if currentVolumeCount+count > int(maxVolumeLimit) { - return framework.NewStatus(framework.Unschedulable, ErrReasonMaxVolumeCountExceeded) - } - } - } - - return nil -} - -// filterAttachableVolumes filters the attachable volumes from the pod and adds them to the result map. -// The result map is a map of volumeUniqueName to driver name. The volumeUniqueName is a unique name for -// the volume in the format of "driverName/volumeHandle". And driver name is the CSI driver name. -func (pl *CSILimits) filterAttachableVolumes( - logger klog.Logger, pod *v1.Pod, csiNode *storagev1.CSINode, newPod bool, result map[string]string) error { - for _, vol := range pod.Spec.Volumes { - pvcName := "" - isEphemeral := false - switch { - case vol.PersistentVolumeClaim != nil: - // Normal CSI volume can only be used through PVC - pvcName = vol.PersistentVolumeClaim.ClaimName - case vol.Ephemeral != nil: - // Generic ephemeral inline volumes also use a PVC, - // just with a computed name and certain ownership. - // That is checked below once the pvc object is - // retrieved. - pvcName = ephemeral.VolumeClaimName(pod, &vol) - isEphemeral = true - default: - // Inline Volume does not have PVC. - // Need to check if CSI migration is enabled for this inline volume. - // - If the volume is migratable and CSI migration is enabled, need to count it - // as well. - // - If the volume is not migratable, it will be count in non_csi filter. - if err := pl.checkAttachableInlineVolume(logger, &vol, csiNode, pod, result); err != nil { - return err - } - - continue - } - - if pvcName == "" { - return fmt.Errorf("PersistentVolumeClaim had no name") - } - - pvc, err := pl.pvcLister.PersistentVolumeClaims(pod.Namespace).Get(pvcName) - - if err != nil { - if newPod { - // The PVC is required to proceed with - // scheduling of a new pod because it cannot - // run without it. Bail out immediately. - return fmt.Errorf("looking up PVC %s/%s: %w", pod.Namespace, pvcName, err) - } - // If the PVC is invalid, we don't count the volume because - // there's no guarantee that it belongs to the running predicate. - logger.V(5).Info("Unable to look up PVC info", "pod", klog.KObj(pod), "PVC", klog.KRef(pod.Namespace, pvcName)) - continue - } - - // The PVC for an ephemeral volume must be owned by the pod. - if isEphemeral { - if err := ephemeral.VolumeIsForPod(pod, pvc); err != nil { - return err - } - } - - driverName, volumeHandle := pl.getCSIDriverInfo(logger, csiNode, pvc) - if driverName == "" || volumeHandle == "" { - logger.V(5).Info("Could not find a CSI driver name or volume handle, not counting volume") - continue - } - - volumeUniqueName := getVolumeUniqueName(driverName, volumeHandle) - result[volumeUniqueName] = driverName - } - return nil -} - -// checkAttachableInlineVolume takes an inline volume and add to the result map if the -// volume is migratable and CSI migration for this plugin has been enabled. -func (pl *CSILimits) checkAttachableInlineVolume(logger klog.Logger, vol *v1.Volume, csiNode *storagev1.CSINode, - pod *v1.Pod, result map[string]string) error { - if !pl.translator.IsInlineMigratable(vol) { - return nil - } - // Check if the intree provisioner CSI migration has been enabled. - inTreeProvisionerName, err := pl.translator.GetInTreePluginNameFromSpec(nil, vol) - if err != nil { - return fmt.Errorf("looking up provisioner name for volume %s: %w", vol.Name, err) - } - if !isCSIMigrationOn(csiNode, inTreeProvisionerName, pl.enableCSIMigrationPortworx) { - csiNodeName := "" - if csiNode != nil { - csiNodeName = csiNode.Name - } - logger.V(5).Info("CSI Migration is not enabled for provisioner", "provisioner", inTreeProvisionerName, - "pod", klog.KObj(pod), "csiNode", csiNodeName) - return nil - } - // Do translation for the in-tree volume. - translatedPV, err := pl.translator.TranslateInTreeInlineVolumeToCSI(logger, vol, pod.Namespace) - if err != nil || translatedPV == nil { - return fmt.Errorf("converting volume(%s) from inline to csi: %w", vol.Name, err) - } - driverName, err := pl.translator.GetCSINameFromInTreeName(inTreeProvisionerName) - if err != nil { - return fmt.Errorf("looking up CSI driver name for provisioner %s: %w", inTreeProvisionerName, err) - } - // TranslateInTreeInlineVolumeToCSI should translate inline volume to CSI. If it is not set, - // the volume does not support inline. Skip the count. - if translatedPV.Spec.PersistentVolumeSource.CSI == nil { - return nil - } - volumeUniqueName := getVolumeUniqueName(driverName, translatedPV.Spec.PersistentVolumeSource.CSI.VolumeHandle) - result[volumeUniqueName] = driverName - return nil -} - -// getCSIDriverInfo returns the CSI driver name and volume ID of a given PVC. -// If the PVC is from a migrated in-tree plugin, this function will return -// the information of the CSI driver that the plugin has been migrated to. -func (pl *CSILimits) getCSIDriverInfo(logger klog.Logger, csiNode *storagev1.CSINode, pvc *v1.PersistentVolumeClaim) (string, string) { - pvName := pvc.Spec.VolumeName - - if pvName == "" { - logger.V(5).Info("Persistent volume had no name for claim", "PVC", klog.KObj(pvc)) - return pl.getCSIDriverInfoFromSC(logger, csiNode, pvc) - } - - pv, err := pl.pvLister.Get(pvName) - if err != nil { - logger.V(5).Info("Unable to look up PV info for PVC and PV", "PVC", klog.KObj(pvc), "PV", klog.KRef("", pvName)) - // If we can't fetch PV associated with PVC, may be it got deleted - // or PVC was prebound to a PVC that hasn't been created yet. - // fallback to using StorageClass for volume counting - return pl.getCSIDriverInfoFromSC(logger, csiNode, pvc) - } - - csiSource := pv.Spec.PersistentVolumeSource.CSI - if csiSource == nil { - // We make a fast path for non-CSI volumes that aren't migratable - if !pl.translator.IsPVMigratable(pv) { - return "", "" - } - - pluginName, err := pl.translator.GetInTreePluginNameFromSpec(pv, nil) - if err != nil { - logger.V(5).Info("Unable to look up plugin name from PV spec", "err", err) - return "", "" - } - - if !isCSIMigrationOn(csiNode, pluginName, pl.enableCSIMigrationPortworx) { - logger.V(5).Info("CSI Migration of plugin is not enabled", "plugin", pluginName) - return "", "" - } - - csiPV, err := pl.translator.TranslateInTreePVToCSI(logger, pv) - if err != nil { - logger.V(5).Info("Unable to translate in-tree volume to CSI", "err", err) - return "", "" - } - - if csiPV.Spec.PersistentVolumeSource.CSI == nil { - logger.V(5).Info("Unable to get a valid volume source for translated PV", "PV", pvName) - return "", "" - } - - csiSource = csiPV.Spec.PersistentVolumeSource.CSI - } - - return csiSource.Driver, csiSource.VolumeHandle -} - -// getCSIDriverInfoFromSC returns the CSI driver name and a random volume ID of a given PVC's StorageClass. -func (pl *CSILimits) getCSIDriverInfoFromSC(logger klog.Logger, csiNode *storagev1.CSINode, pvc *v1.PersistentVolumeClaim) (string, string) { - namespace := pvc.Namespace - pvcName := pvc.Name - scName := storagehelpers.GetPersistentVolumeClaimClass(pvc) - - // If StorageClass is not set or not found, then PVC must be using immediate binding mode - // and hence it must be bound before scheduling. So it is safe to not count it. - if scName == "" { - logger.V(5).Info("PVC has no StorageClass", "PVC", klog.KObj(pvc)) - return "", "" - } - - storageClass, err := pl.scLister.Get(scName) - if err != nil { - logger.V(5).Info("Could not get StorageClass for PVC", "PVC", klog.KObj(pvc), "err", err) - return "", "" - } - - // We use random prefix to avoid conflict with volume IDs. If PVC is bound during the execution of the - // predicate and there is another pod on the same node that uses same volume, then we will overcount - // the volume and consider both volumes as different. - volumeHandle := fmt.Sprintf("%s-%s/%s", pl.randomVolumeIDPrefix, namespace, pvcName) - - provisioner := storageClass.Provisioner - if pl.translator.IsMigratableIntreePluginByName(provisioner) { - if !isCSIMigrationOn(csiNode, provisioner, pl.enableCSIMigrationPortworx) { - logger.V(5).Info("CSI Migration of provisioner is not enabled", "provisioner", provisioner) - return "", "" - } - - driverName, err := pl.translator.GetCSINameFromInTreeName(provisioner) - if err != nil { - logger.V(5).Info("Unable to look up driver name from provisioner name", "provisioner", provisioner, "err", err) - return "", "" - } - return driverName, volumeHandle - } - - return provisioner, volumeHandle -} - -// NewCSI initializes a new plugin and returns it. -func NewCSI(_ context.Context, _ runtime.Object, handle framework.Handle, fts feature.Features) (framework.Plugin, error) { - informerFactory := handle.SharedInformerFactory() - pvLister := informerFactory.Core().V1().PersistentVolumes().Lister() - pvcLister := informerFactory.Core().V1().PersistentVolumeClaims().Lister() - csiNodesLister := informerFactory.Storage().V1().CSINodes().Lister() - scLister := informerFactory.Storage().V1().StorageClasses().Lister() - vaLister := informerFactory.Storage().V1().VolumeAttachments().Lister() - csiTranslator := csitrans.New() - - return &CSILimits{ - csiNodeLister: csiNodesLister, - pvLister: pvLister, - pvcLister: pvcLister, - scLister: scLister, - vaLister: vaLister, - enableCSIMigrationPortworx: fts.EnableCSIMigrationPortworx, - randomVolumeIDPrefix: rand.String(32), - translator: csiTranslator, - }, nil -} - -// getVolumeLimits reads the volume limits from CSINode object and returns a map of volume limits. -// The key is the driver name and the value is the maximum number of volumes that can be attached to the node. -// If a key is not found in the map, it means there is no limit for the driver on the node. -func getVolumeLimits(csiNode *storagev1.CSINode) map[string]int64 { - nodeVolumeLimits := make(map[string]int64) - if csiNode == nil { - return nodeVolumeLimits - } - for _, d := range csiNode.Spec.Drivers { - if d.Allocatable != nil && d.Allocatable.Count != nil { - nodeVolumeLimits[d.Name] = int64(*d.Allocatable.Count) - } - } - return nodeVolumeLimits -} - -// getNodeVolumeAttachmentInfo returns a map of volumeID to driver name for the given node. -func (pl *CSILimits) getNodeVolumeAttachmentInfo(logger klog.Logger, nodeName string) (map[string]string, error) { - volumeAttachments := make(map[string]string) - vas, err := pl.vaLister.List(labels.Everything()) - if err != nil { - return nil, err - } - for _, va := range vas { - if va.Spec.NodeName == nodeName { - if va.Spec.Attacher == "" { - logger.V(5).Info("VolumeAttachment has no attacher", "VolumeAttachment", klog.KObj(va)) - continue - } - if va.Spec.Source.PersistentVolumeName == nil { - logger.V(5).Info("VolumeAttachment has no PV name", "VolumeAttachment", klog.KObj(va)) - continue - } - pv, err := pl.pvLister.Get(*va.Spec.Source.PersistentVolumeName) - if err != nil { - logger.V(5).Info("Unable to get PV for VolumeAttachment", "VolumeAttachment", klog.KObj(va), "err", err) - continue - } - if pv.Spec.CSI == nil { - logger.V(5).Info("PV is not a CSI volume", "PV", klog.KObj(pv)) - continue - } - volumeID := getVolumeUniqueName(va.Spec.Attacher, pv.Spec.CSI.VolumeHandle) - volumeAttachments[volumeID] = va.Spec.Attacher - } - } - return volumeAttachments, nil -} - -func getVolumeUniqueName(driverName, volumeHandle string) string { - return fmt.Sprintf("%s/%s", driverName, volumeHandle) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go deleted file mode 100644 index 7cb761379..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits/utils.go +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package nodevolumelimits - -import ( - "strings" - - v1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" - "k8s.io/apimachinery/pkg/util/sets" - csilibplugins "k8s.io/csi-translation-lib/plugins" -) - -// isCSIMigrationOn returns a boolean value indicating whether -// the CSI migration has been enabled for a particular storage plugin. -func isCSIMigrationOn(csiNode *storagev1.CSINode, pluginName string, enableCSIMigrationPortworx bool) bool { - if csiNode == nil || len(pluginName) == 0 { - return false - } - - // In-tree storage to CSI driver migration feature should be enabled, - // along with the plugin-specific one - switch pluginName { - case csilibplugins.AWSEBSInTreePluginName: - return true - case csilibplugins.PortworxVolumePluginName: - if !enableCSIMigrationPortworx { - return false - } - case csilibplugins.GCEPDInTreePluginName: - return true - case csilibplugins.AzureDiskInTreePluginName: - return true - case csilibplugins.CinderInTreePluginName: - return true - default: - return false - } - - // The plugin name should be listed in the CSINode object annotation. - // This indicates that the plugin has been migrated to a CSI driver in the node. - csiNodeAnn := csiNode.GetAnnotations() - if csiNodeAnn == nil { - return false - } - - var mpaSet sets.Set[string] - mpa := csiNodeAnn[v1.MigratedPluginsAnnotationKey] - if len(mpa) == 0 { - mpaSet = sets.New[string]() - } else { - tok := strings.Split(mpa, ",") - mpaSet = sets.New(tok...) - } - - return mpaSet.Has(pluginName) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/common.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/common.go deleted file mode 100644 index 5896aad65..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/common.go +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package podtopologyspread - -import ( - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - v1helper "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" - "k8s.io/utils/ptr" -) - -// topologySpreadConstraint is an internal version for v1.TopologySpreadConstraint -// and where the selector is parsed. -// Fields are exported for comparison during testing. -type topologySpreadConstraint struct { - MaxSkew int32 - TopologyKey string - Selector labels.Selector - MinDomains int32 - NodeAffinityPolicy v1.NodeInclusionPolicy - NodeTaintsPolicy v1.NodeInclusionPolicy -} - -func (tsc *topologySpreadConstraint) matchNodeInclusionPolicies(pod *v1.Pod, node *v1.Node, require nodeaffinity.RequiredNodeAffinity) bool { - if tsc.NodeAffinityPolicy == v1.NodeInclusionPolicyHonor { - // We ignore parsing errors here for backwards compatibility. - if match, _ := require.Match(node); !match { - return false - } - } - - if tsc.NodeTaintsPolicy == v1.NodeInclusionPolicyHonor { - if _, untolerated := v1helper.FindMatchingUntoleratedTaint(node.Spec.Taints, pod.Spec.Tolerations, helper.DoNotScheduleTaintsFilterFunc()); untolerated { - return false - } - } - return true -} - -// buildDefaultConstraints builds the constraints for a pod using -// .DefaultConstraints and the selectors from the services, replication -// controllers, replica sets and stateful sets that match the pod. -func (pl *PodTopologySpread) buildDefaultConstraints(p *v1.Pod, action v1.UnsatisfiableConstraintAction) ([]topologySpreadConstraint, error) { - constraints, err := pl.filterTopologySpreadConstraints(pl.defaultConstraints, p.Labels, action) - if err != nil || len(constraints) == 0 { - return nil, err - } - selector := helper.DefaultSelector(p, pl.services, pl.replicationCtrls, pl.replicaSets, pl.statefulSets) - if selector.Empty() { - return nil, nil - } - for i := range constraints { - constraints[i].Selector = selector - } - return constraints, nil -} - -// nodeLabelsMatchSpreadConstraints checks if ALL topology keys in spread Constraints are present in node labels. -func nodeLabelsMatchSpreadConstraints(nodeLabels map[string]string, constraints []topologySpreadConstraint) bool { - for _, c := range constraints { - if _, ok := nodeLabels[c.TopologyKey]; !ok { - return false - } - } - return true -} - -func (pl *PodTopologySpread) filterTopologySpreadConstraints(constraints []v1.TopologySpreadConstraint, podLabels map[string]string, action v1.UnsatisfiableConstraintAction) ([]topologySpreadConstraint, error) { - var result []topologySpreadConstraint - for _, c := range constraints { - if c.WhenUnsatisfiable == action { - selector, err := metav1.LabelSelectorAsSelector(c.LabelSelector) - if err != nil { - return nil, err - } - - if pl.enableMatchLabelKeysInPodTopologySpread && len(c.MatchLabelKeys) > 0 { - matchLabels := make(labels.Set) - for _, labelKey := range c.MatchLabelKeys { - if value, ok := podLabels[labelKey]; ok { - matchLabels[labelKey] = value - } - } - if len(matchLabels) > 0 { - selector = mergeLabelSetWithSelector(matchLabels, selector) - } - } - - tsc := topologySpreadConstraint{ - MaxSkew: c.MaxSkew, - TopologyKey: c.TopologyKey, - Selector: selector, - MinDomains: ptr.Deref(c.MinDomains, 1), // If MinDomains is nil, we treat MinDomains as 1. - NodeAffinityPolicy: v1.NodeInclusionPolicyHonor, // If NodeAffinityPolicy is nil, we treat NodeAffinityPolicy as "Honor". - NodeTaintsPolicy: v1.NodeInclusionPolicyIgnore, // If NodeTaintsPolicy is nil, we treat NodeTaintsPolicy as "Ignore". - } - if pl.enableNodeInclusionPolicyInPodTopologySpread { - if c.NodeAffinityPolicy != nil { - tsc.NodeAffinityPolicy = *c.NodeAffinityPolicy - } - if c.NodeTaintsPolicy != nil { - tsc.NodeTaintsPolicy = *c.NodeTaintsPolicy - } - } - result = append(result, tsc) - } - } - return result, nil -} - -func mergeLabelSetWithSelector(matchLabels labels.Set, s labels.Selector) labels.Selector { - mergedSelector := labels.SelectorFromSet(matchLabels) - - requirements, ok := s.Requirements() - if !ok { - return s - } - - for _, r := range requirements { - mergedSelector = mergedSelector.Add(r) - } - - return mergedSelector -} - -func countPodsMatchSelector(podInfos []*framework.PodInfo, selector labels.Selector, ns string) int { - if selector.Empty() { - return 0 - } - count := 0 - for _, p := range podInfos { - // Bypass terminating Pod (see #87621). - if p.Pod.DeletionTimestamp != nil || p.Pod.Namespace != ns { - continue - } - if selector.Matches(labels.Set(p.Pod.Labels)) { - count++ - } - } - return count -} - -// podLabelsMatchSpreadConstraints returns whether tha labels matches with the selector in any of topologySpreadConstraint -func podLabelsMatchSpreadConstraints(constraints []topologySpreadConstraint, labels labels.Set) bool { - for _, c := range constraints { - if c.Selector.Matches(labels) { - return true - } - } - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go deleted file mode 100644 index 2b0d5d8f3..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go +++ /dev/null @@ -1,367 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package podtopologyspread - -import ( - "context" - "fmt" - "maps" - "math" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -const preFilterStateKey = "PreFilter" + Name - -// preFilterState computed at PreFilter and used at Filter. -// It combines CriticalPaths and TpValueToMatchNum to represent: -// (1) critical paths where the least pods are matched on each spread constraint. -// (2) number of pods matched on each spread constraint. -// A nil preFilterState denotes it's not set at all (in PreFilter phase); -// An empty preFilterState object denotes it's a legit state and is set in PreFilter phase. -// Fields are exported for comparison during testing. -type preFilterState struct { - Constraints []topologySpreadConstraint - // CriticalPaths is a slice indexed by constraint index. - // Per each entry, we record 2 critical paths instead of all critical paths. - // CriticalPaths[i][0].MatchNum always holds the minimum matching number. - // CriticalPaths[i][1].MatchNum is always greater or equal to CriticalPaths[i][0].MatchNum, but - // it's not guaranteed to be the 2nd minimum match number. - CriticalPaths []*criticalPaths - // TpValueToMatchNum is a slice indexed by constraint index. - // Each entry is keyed with topology value, and valued with the number of matching pods. - TpValueToMatchNum []map[string]int -} - -// minMatchNum returns the global minimum for the calculation of skew while taking MinDomains into account. -func (s *preFilterState) minMatchNum(constraintID int, minDomains int32) (int, error) { - paths := s.CriticalPaths[constraintID] - - minMatchNum := paths[0].MatchNum - domainsNum := len(s.TpValueToMatchNum[constraintID]) - - if domainsNum < int(minDomains) { - // When the number of eligible domains with matching topology keys is less than `minDomains`, - // it treats "global minimum" as 0. - minMatchNum = 0 - } - - return minMatchNum, nil -} - -// Clone makes a copy of the given state. -func (s *preFilterState) Clone() framework.StateData { - if s == nil { - return nil - } - copy := preFilterState{ - // Constraints are shared because they don't change. - Constraints: s.Constraints, - CriticalPaths: make([]*criticalPaths, len(s.CriticalPaths)), - TpValueToMatchNum: make([]map[string]int, len(s.TpValueToMatchNum)), - } - for i, paths := range s.CriticalPaths { - copy.CriticalPaths[i] = &criticalPaths{paths[0], paths[1]} - } - for i, tpMap := range s.TpValueToMatchNum { - copy.TpValueToMatchNum[i] = maps.Clone(tpMap) - } - return © -} - -// CAVEAT: the reason that `[2]criticalPath` can work is based on the implementation of current -// preemption algorithm, in particular the following 2 facts: -// Fact 1: we only preempt pods on the same node, instead of pods on multiple nodes. -// Fact 2: each node is evaluated on a separate copy of the preFilterState during its preemption cycle. -// If we plan to turn to a more complex algorithm like "arbitrary pods on multiple nodes", this -// structure needs to be revisited. -// Fields are exported for comparison during testing. -type criticalPaths [2]struct { - // TopologyValue denotes the topology value mapping to topology key. - TopologyValue string - // MatchNum denotes the number of matching pods. - MatchNum int -} - -func newCriticalPaths() *criticalPaths { - return &criticalPaths{{MatchNum: math.MaxInt32}, {MatchNum: math.MaxInt32}} -} - -func (p *criticalPaths) update(tpVal string, num int) { - // first verify if `tpVal` exists or not - i := -1 - if tpVal == p[0].TopologyValue { - i = 0 - } else if tpVal == p[1].TopologyValue { - i = 1 - } - - if i >= 0 { - // `tpVal` exists - p[i].MatchNum = num - if p[0].MatchNum > p[1].MatchNum { - // swap paths[0] and paths[1] - p[0], p[1] = p[1], p[0] - } - } else { - // `tpVal` doesn't exist - if num < p[0].MatchNum { - // update paths[1] with paths[0] - p[1] = p[0] - // update paths[0] - p[0].TopologyValue, p[0].MatchNum = tpVal, num - } else if num < p[1].MatchNum { - // update paths[1] - p[1].TopologyValue, p[1].MatchNum = tpVal, num - } - } -} - -// PreFilter invoked at the prefilter extension point. -func (pl *PodTopologySpread) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - s, err := pl.calPreFilterState(ctx, pod) - if err != nil { - return nil, framework.AsStatus(err) - } else if s != nil && len(s.Constraints) == 0 { - return nil, framework.NewStatus(framework.Skip) - } - - cycleState.Write(preFilterStateKey, s) - return nil, nil -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (pl *PodTopologySpread) PreFilterExtensions() framework.PreFilterExtensions { - return pl -} - -// AddPod from pre-computed data in cycleState. -func (pl *PodTopologySpread) AddPod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToAdd *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - s, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - - pl.updateWithPod(s, podInfoToAdd.Pod, podToSchedule, nodeInfo.Node(), 1) - return nil -} - -// RemovePod from pre-computed data in cycleState. -func (pl *PodTopologySpread) RemovePod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToRemove *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - s, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - - pl.updateWithPod(s, podInfoToRemove.Pod, podToSchedule, nodeInfo.Node(), -1) - return nil -} - -func (pl *PodTopologySpread) updateWithPod(s *preFilterState, updatedPod, preemptorPod *v1.Pod, node *v1.Node, delta int) { - if s == nil || updatedPod.Namespace != preemptorPod.Namespace || node == nil { - return - } - if !nodeLabelsMatchSpreadConstraints(node.Labels, s.Constraints) { - return - } - - requiredSchedulingTerm := nodeaffinity.GetRequiredNodeAffinity(preemptorPod) - if !pl.enableNodeInclusionPolicyInPodTopologySpread { - // spreading is applied to nodes that pass those filters. - // Ignore parsing errors for backwards compatibility. - if match, _ := requiredSchedulingTerm.Match(node); !match { - return - } - } - - podLabelSet := labels.Set(updatedPod.Labels) - for i, constraint := range s.Constraints { - if !constraint.Selector.Matches(podLabelSet) { - continue - } - - if pl.enableNodeInclusionPolicyInPodTopologySpread && - !constraint.matchNodeInclusionPolicies(preemptorPod, node, requiredSchedulingTerm) { - continue - } - - v := node.Labels[constraint.TopologyKey] - s.TpValueToMatchNum[i][v] += delta - s.CriticalPaths[i].update(v, s.TpValueToMatchNum[i][v]) - } -} - -// getPreFilterState fetches a pre-computed preFilterState. -func getPreFilterState(cycleState *framework.CycleState) (*preFilterState, error) { - c, err := cycleState.Read(preFilterStateKey) - if err != nil { - // preFilterState doesn't exist, likely PreFilter wasn't invoked. - return nil, fmt.Errorf("reading %q from cycleState: %w", preFilterStateKey, err) - } - - s, ok := c.(*preFilterState) - if !ok { - return nil, fmt.Errorf("%+v convert to podtopologyspread.preFilterState error", c) - } - return s, nil -} - -type topologyCount struct { - topologyValue string - constraintID int - count int -} - -// calPreFilterState computes preFilterState describing how pods are spread on topologies. -func (pl *PodTopologySpread) calPreFilterState(ctx context.Context, pod *v1.Pod) (*preFilterState, error) { - constraints, err := pl.getConstraints(pod) - if err != nil { - return nil, fmt.Errorf("get constraints from pod: %w", err) - } - if len(constraints) == 0 { - return &preFilterState{}, nil - } - - allNodes, err := pl.sharedLister.NodeInfos().List() - if err != nil { - return nil, fmt.Errorf("listing NodeInfos: %w", err) - } - - s := preFilterState{ - Constraints: constraints, - CriticalPaths: make([]*criticalPaths, len(constraints)), - TpValueToMatchNum: make([]map[string]int, len(constraints)), - } - for i := 0; i < len(constraints); i++ { - s.TpValueToMatchNum[i] = make(map[string]int, sizeHeuristic(len(allNodes), constraints[i])) - } - - tpCountsByNode := make([][]topologyCount, len(allNodes)) - requiredNodeAffinity := nodeaffinity.GetRequiredNodeAffinity(pod) - processNode := func(n int) { - nodeInfo := allNodes[n] - node := nodeInfo.Node() - - if !pl.enableNodeInclusionPolicyInPodTopologySpread { - // spreading is applied to nodes that pass those filters. - // Ignore parsing errors for backwards compatibility. - if match, _ := requiredNodeAffinity.Match(node); !match { - return - } - } - - // Ensure current node's labels contains all topologyKeys in 'Constraints'. - if !nodeLabelsMatchSpreadConstraints(node.Labels, constraints) { - return - } - - tpCounts := make([]topologyCount, 0, len(constraints)) - for i, c := range constraints { - if pl.enableNodeInclusionPolicyInPodTopologySpread && - !c.matchNodeInclusionPolicies(pod, node, requiredNodeAffinity) { - continue - } - - value := node.Labels[c.TopologyKey] - count := countPodsMatchSelector(nodeInfo.Pods, c.Selector, pod.Namespace) - tpCounts = append(tpCounts, topologyCount{ - topologyValue: value, - constraintID: i, - count: count, - }) - } - tpCountsByNode[n] = tpCounts - } - pl.parallelizer.Until(ctx, len(allNodes), processNode, pl.Name()) - - for _, tpCounts := range tpCountsByNode { - // tpCounts might not hold all the constraints, so index can't be used here as constraintID. - for _, tpCount := range tpCounts { - s.TpValueToMatchNum[tpCount.constraintID][tpCount.topologyValue] += tpCount.count - } - } - - // calculate min match for each constraint and topology value - for i := 0; i < len(constraints); i++ { - s.CriticalPaths[i] = newCriticalPaths() - - for value, num := range s.TpValueToMatchNum[i] { - s.CriticalPaths[i].update(value, num) - } - } - - return &s, nil -} - -// Filter invoked at the filter extension point. -func (pl *PodTopologySpread) Filter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - node := nodeInfo.Node() - - s, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - - // However, "empty" preFilterState is legit which tolerates every toSchedule Pod. - if len(s.Constraints) == 0 { - return nil - } - - logger := klog.FromContext(ctx) - podLabelSet := labels.Set(pod.Labels) - for i, c := range s.Constraints { - tpKey := c.TopologyKey - tpVal, ok := node.Labels[tpKey] - if !ok { - logger.V(5).Info("Node doesn't have required topology label for spread constraint", "node", klog.KObj(node), "topologyKey", tpKey) - return framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonNodeLabelNotMatch) - } - - // judging criteria: - // 'existing matching num' + 'if self-match (1 or 0)' - 'global minimum' <= 'maxSkew' - minMatchNum, err := s.minMatchNum(i, c.MinDomains) - if err != nil { - logger.Error(err, "Internal error occurred while retrieving value precalculated in PreFilter", "topologyKey", tpKey, "paths", s.CriticalPaths[i]) - continue - } - - selfMatchNum := 0 - if c.Selector.Matches(podLabelSet) { - selfMatchNum = 1 - } - - matchNum := s.TpValueToMatchNum[i][tpVal] - skew := matchNum + selfMatchNum - minMatchNum - if skew > int(c.MaxSkew) { - logger.V(5).Info("Node failed spreadConstraint: matchNum + selfMatchNum - minMatchNum > maxSkew", "node", klog.KObj(node), "topologyKey", tpKey, "matchNum", matchNum, "selfMatchNum", selfMatchNum, "minMatchNum", minMatchNum, "maxSkew", c.MaxSkew) - return framework.NewStatus(framework.Unschedulable, ErrReasonConstraintsNotMatch) - } - } - - return nil -} - -func sizeHeuristic(nodes int, constraint topologySpreadConstraint) int { - if constraint.TopologyKey == v1.LabelHostname { - return nodes - } - return 0 -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go deleted file mode 100644 index 4295755ca..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/plugin.go +++ /dev/null @@ -1,351 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package podtopologyspread - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/equality" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/informers" - appslisters "k8s.io/client-go/listers/apps/v1" - corelisters "k8s.io/client-go/listers/core/v1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -const ( - // ErrReasonConstraintsNotMatch is used for PodTopologySpread filter error. - ErrReasonConstraintsNotMatch = "node(s) didn't match pod topology spread constraints" - // ErrReasonNodeLabelNotMatch is used when the node doesn't hold the required label. - ErrReasonNodeLabelNotMatch = ErrReasonConstraintsNotMatch + " (missing required label)" -) - -var systemDefaultConstraints = []v1.TopologySpreadConstraint{ - { - TopologyKey: v1.LabelHostname, - WhenUnsatisfiable: v1.ScheduleAnyway, - MaxSkew: 3, - }, - { - TopologyKey: v1.LabelTopologyZone, - WhenUnsatisfiable: v1.ScheduleAnyway, - MaxSkew: 5, - }, -} - -// PodTopologySpread is a plugin that ensures pod's topologySpreadConstraints is satisfied. -type PodTopologySpread struct { - systemDefaulted bool - parallelizer parallelize.Parallelizer - defaultConstraints []v1.TopologySpreadConstraint - sharedLister framework.SharedLister - services corelisters.ServiceLister - replicationCtrls corelisters.ReplicationControllerLister - replicaSets appslisters.ReplicaSetLister - statefulSets appslisters.StatefulSetLister - enableNodeInclusionPolicyInPodTopologySpread bool - enableMatchLabelKeysInPodTopologySpread bool - enableSchedulingQueueHint bool -} - -var _ framework.PreFilterPlugin = &PodTopologySpread{} -var _ framework.FilterPlugin = &PodTopologySpread{} -var _ framework.PreScorePlugin = &PodTopologySpread{} -var _ framework.ScorePlugin = &PodTopologySpread{} -var _ framework.EnqueueExtensions = &PodTopologySpread{} - -// Name is the name of the plugin used in the plugin registry and configurations. -const Name = names.PodTopologySpread - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *PodTopologySpread) Name() string { - return Name -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, plArgs runtime.Object, h framework.Handle, fts feature.Features) (framework.Plugin, error) { - if h.SnapshotSharedLister() == nil { - return nil, fmt.Errorf("SnapshotSharedlister is nil") - } - args, err := getArgs(plArgs) - if err != nil { - return nil, err - } - if err := validation.ValidatePodTopologySpreadArgs(nil, &args); err != nil { - return nil, err - } - pl := &PodTopologySpread{ - parallelizer: h.Parallelizer(), - sharedLister: h.SnapshotSharedLister(), - defaultConstraints: args.DefaultConstraints, - enableNodeInclusionPolicyInPodTopologySpread: fts.EnableNodeInclusionPolicyInPodTopologySpread, - enableMatchLabelKeysInPodTopologySpread: fts.EnableMatchLabelKeysInPodTopologySpread, - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - } - if args.DefaultingType == config.SystemDefaulting { - pl.defaultConstraints = systemDefaultConstraints - pl.systemDefaulted = true - } - if len(pl.defaultConstraints) != 0 { - if h.SharedInformerFactory() == nil { - return nil, fmt.Errorf("SharedInformerFactory is nil") - } - pl.setListers(h.SharedInformerFactory()) - } - return pl, nil -} - -func getArgs(obj runtime.Object) (config.PodTopologySpreadArgs, error) { - ptr, ok := obj.(*config.PodTopologySpreadArgs) - if !ok { - return config.PodTopologySpreadArgs{}, fmt.Errorf("want args to be of type PodTopologySpreadArgs, got %T", obj) - } - return *ptr, nil -} - -func (pl *PodTopologySpread) setListers(factory informers.SharedInformerFactory) { - pl.services = factory.Core().V1().Services().Lister() - pl.replicationCtrls = factory.Core().V1().ReplicationControllers().Lister() - pl.replicaSets = factory.Apps().V1().ReplicaSets().Lister() - pl.statefulSets = factory.Apps().V1().StatefulSets().Lister() -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *PodTopologySpread) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - podActionType := framework.Add | framework.UpdatePodLabel | framework.Delete - if pl.enableSchedulingQueueHint { - // When the QueueingHint feature is enabled, the scheduling queue uses Pod/Update Queueing Hint - // to determine whether a Pod's update makes the Pod schedulable or not. - // https://github.com/kubernetes/kubernetes/pull/122234 - // (If not, the scheduling queue always retries the unschedulable Pods when they're updated.) - // - // The Pod rejected by this plugin can be schedulable when the Pod has a spread constraint with NodeTaintsPolicy:Honor - // and has got a new toleration. - // So, we add UpdatePodToleration here only when QHint is enabled. - podActionType = framework.Add | framework.UpdatePodLabel | framework.UpdatePodToleration | framework.Delete - } - - return []framework.ClusterEventWithHint{ - // All ActionType includes the following events: - // - Add. An unschedulable Pod may fail due to violating topology spread constraints, - // adding an assigned Pod may make it schedulable. - // - UpdatePodLabel. Updating on an existing Pod's labels (e.g., removal) may make - // an unschedulable Pod schedulable. - // - Delete. An unschedulable Pod may fail due to violating an existing Pod's topology spread constraints, - // deleting an existing Pod may make it schedulable. - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: podActionType}, QueueingHintFn: pl.isSchedulableAfterPodChange}, - // Node add|delete|update maybe lead an topology key changed, - // and make these pod in scheduling schedulable or unschedulable. - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.Delete | framework.UpdateNodeLabel | framework.UpdateNodeTaint}, QueueingHintFn: pl.isSchedulableAfterNodeChange}, - }, nil -} - -// involvedInTopologySpreading returns true if the incomingPod is involved in the topology spreading of podWithSpreading. -func involvedInTopologySpreading(incomingPod, podWithSpreading *v1.Pod) bool { - return incomingPod.UID == podWithSpreading.UID || - (incomingPod.Spec.NodeName != "" && incomingPod.Namespace == podWithSpreading.Namespace) -} - -// hasConstraintWithNodeTaintsPolicyHonor returns true if any constraint has `NodeTaintsPolicy: Honor`. -func hasConstraintWithNodeTaintsPolicyHonor(constraints []topologySpreadConstraint) bool { - for _, c := range constraints { - if c.NodeTaintsPolicy == v1.NodeInclusionPolicyHonor { - return true - } - } - return false -} - -func (pl *PodTopologySpread) isSchedulableAfterPodChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalPod, modifiedPod, err := util.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - if (modifiedPod != nil && !involvedInTopologySpreading(modifiedPod, pod)) || (originalPod != nil && !involvedInTopologySpreading(originalPod, pod)) { - logger.V(5).Info("the added/updated/deleted pod is unscheduled or has different namespace with target pod, so it doesn't make the target pod schedulable", - "pod", klog.KObj(pod), "originalPod", klog.KObj(originalPod)) - return framework.QueueSkip, nil - } - - constraints, err := pl.getConstraints(pod) - if err != nil { - return framework.Queue, err - } - - // Pod is modified. Return Queue when the label(s) matching topologySpread's selector is added, changed, or deleted. - if modifiedPod != nil && originalPod != nil { - if pod.UID == modifiedPod.UID && !equality.Semantic.DeepEqual(modifiedPod.Spec.Tolerations, originalPod.Spec.Tolerations) && hasConstraintWithNodeTaintsPolicyHonor(constraints) { - // If any constraint has `NodeTaintsPolicy: Honor`, we can return Queue when the target Pod has got a new toleration. - logger.V(5).Info("the unschedulable pod has got a new toleration, which could make it schedulable", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - - if equality.Semantic.DeepEqual(modifiedPod.Labels, originalPod.Labels) { - logger.V(5).Info("the pod's update doesn't include the label update, which doesn't make the target pod schedulable", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - for _, c := range constraints { - if c.Selector.Matches(labels.Set(originalPod.Labels)) != c.Selector.Matches(labels.Set(modifiedPod.Labels)) { - // This modification makes this Pod match(or not match) with this constraint. - // Maybe now the scheduling result of topology spread gets changed by this change. - logger.V(5).Info("a scheduled pod's label was updated and it makes the updated pod match or unmatch the pod's topology spread constraints", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - } - // This modification of labels doesn't change whether this Pod would match selector or not in any constraints. - logger.V(5).Info("a scheduled pod's label was updated, but it's a change unrelated to the pod's topology spread constraints", - "pod", klog.KObj(pod), "modifiedPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - // Pod is added. Return Queue when the added Pod has a label that matches with topologySpread's selector. - if modifiedPod != nil { - if podLabelsMatchSpreadConstraints(constraints, modifiedPod.Labels) { - logger.V(5).Info("a scheduled pod was created and it matches with the pod's topology spread constraints", - "pod", klog.KObj(pod), "createdPod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - logger.V(5).Info("a scheduled pod was created, but it doesn't matches with the pod's topology spread constraints", - "pod", klog.KObj(pod), "createdPod", klog.KObj(modifiedPod)) - return framework.QueueSkip, nil - } - - // Pod is deleted. Return Queue when the deleted Pod has a label that matches with topologySpread's selector. - if podLabelsMatchSpreadConstraints(constraints, originalPod.Labels) { - logger.V(5).Info("a scheduled pod which matches with the pod's topology spread constraints was deleted, and the pod may be schedulable now", - "pod", klog.KObj(pod), "deletedPod", klog.KObj(originalPod)) - return framework.Queue, nil - } - logger.V(5).Info("a scheduled pod was deleted, but it's unrelated to the pod's topology spread constraints", - "pod", klog.KObj(pod), "deletedPod", klog.KObj(originalPod)) - - return framework.QueueSkip, nil -} - -// getConstraints extracts topologySpreadConstraint(s) from the Pod spec. -// If the Pod doesn't have any topologySpreadConstraint, it returns default constraints. -func (pl *PodTopologySpread) getConstraints(pod *v1.Pod) ([]topologySpreadConstraint, error) { - var constraints []topologySpreadConstraint - var err error - if len(pod.Spec.TopologySpreadConstraints) > 0 { - // We have feature gating in APIServer to strip the spec - // so don't need to re-check feature gate, just check length of Constraints. - constraints, err = pl.filterTopologySpreadConstraints( - pod.Spec.TopologySpreadConstraints, - pod.Labels, - v1.DoNotSchedule, - ) - if err != nil { - return nil, fmt.Errorf("obtaining pod's hard topology spread constraints: %w", err) - } - } else { - constraints, err = pl.buildDefaultConstraints(pod, v1.DoNotSchedule) - if err != nil { - return nil, fmt.Errorf("setting default hard topology spread constraints: %w", err) - } - } - return constraints, nil -} - -// isSchedulableAfterNodeChange returns Queue when node has topologyKey in its labels, else return QueueSkip. -func (pl *PodTopologySpread) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalNode, modifiedNode, err := util.As[*v1.Node](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - constraints, err := pl.getConstraints(pod) - if err != nil { - return framework.Queue, err - } - - var originalNodeMatching, modifiedNodeMatching bool - if originalNode != nil { - originalNodeMatching = nodeLabelsMatchSpreadConstraints(originalNode.Labels, constraints) - } - if modifiedNode != nil { - modifiedNodeMatching = nodeLabelsMatchSpreadConstraints(modifiedNode.Labels, constraints) - } - - // We return Queue in the following cases: - // 1. Node/UpdateNodeLabel: - // - The original node matched the pod's topology spread constraints, but the modified node does not. - // - The modified node matches the pod's topology spread constraints, but the original node does not. - // - The modified node matches the pod's topology spread constraints, and the original node and the modified node have different label values for any topologyKey. - // 2. Node/UpdateNodeTaint: - // - The modified node match the pod's topology spread constraints, and the original node and the modified node have different taints. - // 3. Node/Add: The created node matches the pod's topology spread constraints. - // 4. Node/Delete: The original node matched the pod's topology spread constraints. - if originalNode != nil && modifiedNode != nil { - if originalNodeMatching != modifiedNodeMatching { - logger.V(5).Info("the node is updated and now pod topology spread constraints has changed, and the pod may be schedulable now", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode), "originalMatching", originalNodeMatching, "newMatching", modifiedNodeMatching) - return framework.Queue, nil - } - if modifiedNodeMatching && (checkTopologyKeyLabelsChanged(originalNode.Labels, modifiedNode.Labels, constraints) || !equality.Semantic.DeepEqual(originalNode.Spec.Taints, modifiedNode.Spec.Taints)) { - logger.V(5).Info("the node is updated and now has different taints or labels, and the pod may be schedulable now", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - return framework.QueueSkip, nil - } - - if modifiedNode != nil { - if !modifiedNodeMatching { - logger.V(5).Info("the created node doesn't match pod topology spread constraints", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil - } - logger.V(5).Info("the created node matches topology spread constraints, and the pod may be schedulable now", - "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - - if !originalNodeMatching { - logger.V(5).Info("the deleted node doesn't match pod topology spread constraints", "pod", klog.KObj(pod), "node", klog.KObj(originalNode)) - return framework.QueueSkip, nil - } - logger.V(5).Info("the deleted node matches topology spread constraints, and the pod may be schedulable now", - "pod", klog.KObj(pod), "node", klog.KObj(originalNode)) - return framework.Queue, nil -} - -// checkTopologyKeyLabelsChanged checks if any of the labels specified as topologyKey in the constraints have changed. -func checkTopologyKeyLabelsChanged(originalLabels, modifiedLabels map[string]string, constraints []topologySpreadConstraint) bool { - for _, constraint := range constraints { - topologyKey := constraint.TopologyKey - if originalLabels[topologyKey] != modifiedLabels[topologyKey] { - return true - } - } - return false -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/scoring.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/scoring.go deleted file mode 100644 index ed8a9542f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread/scoring.go +++ /dev/null @@ -1,303 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package podtopologyspread - -import ( - "context" - "fmt" - "math" - "sync/atomic" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/component-helpers/scheduling/corev1/nodeaffinity" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -const preScoreStateKey = "PreScore" + Name -const invalidScore = -1 - -// preScoreState computed at PreScore and used at Score. -// Fields are exported for comparison during testing. -type preScoreState struct { - Constraints []topologySpreadConstraint - // IgnoredNodes is a set of node names which miss some Constraints[*].topologyKey. - IgnoredNodes sets.Set[string] - // TopologyValueToPodCounts is a slice indexed by constraint index. - // Each entry is keyed with topology value, and valued with the number of matching pods. - TopologyValueToPodCounts []map[string]*int64 - // TopologyNormalizingWeight is the weight we give to the counts per topology. - // This allows the pod counts of smaller topologies to not be watered down by - // bigger ones. - TopologyNormalizingWeight []float64 -} - -// Clone implements the mandatory Clone interface. We don't really copy the data since -// there is no need for that. -func (s *preScoreState) Clone() framework.StateData { - return s -} - -// initPreScoreState iterates "filteredNodes" to filter out the nodes which -// don't have required topologyKey(s), and initialize: -// 1) s.TopologyPairToPodCounts: keyed with both eligible topology pair and node names. -// 2) s.IgnoredNodes: the set of nodes that shouldn't be scored. -// 3) s.TopologyNormalizingWeight: The weight to be given to each constraint based on the number of values in a topology. -func (pl *PodTopologySpread) initPreScoreState(s *preScoreState, pod *v1.Pod, filteredNodes []*framework.NodeInfo, requireAllTopologies bool) error { - var err error - if len(pod.Spec.TopologySpreadConstraints) > 0 { - s.Constraints, err = pl.filterTopologySpreadConstraints( - pod.Spec.TopologySpreadConstraints, - pod.Labels, - v1.ScheduleAnyway, - ) - if err != nil { - return fmt.Errorf("obtaining pod's soft topology spread constraints: %w", err) - } - } else { - s.Constraints, err = pl.buildDefaultConstraints(pod, v1.ScheduleAnyway) - if err != nil { - return fmt.Errorf("setting default soft topology spread constraints: %w", err) - } - } - if len(s.Constraints) == 0 { - return nil - } - s.TopologyValueToPodCounts = make([]map[string]*int64, len(s.Constraints)) - for i := 0; i < len(s.Constraints); i++ { - s.TopologyValueToPodCounts[i] = make(map[string]*int64) - } - topoSize := make([]int, len(s.Constraints)) - for _, node := range filteredNodes { - if requireAllTopologies && !nodeLabelsMatchSpreadConstraints(node.Node().Labels, s.Constraints) { - // Nodes which don't have all required topologyKeys present are ignored - // when scoring later. - s.IgnoredNodes.Insert(node.Node().Name) - continue - } - for i, constraint := range s.Constraints { - // per-node counts are calculated during Score. - if constraint.TopologyKey == v1.LabelHostname { - continue - } - value := node.Node().Labels[constraint.TopologyKey] - if s.TopologyValueToPodCounts[i][value] == nil { - s.TopologyValueToPodCounts[i][value] = new(int64) - topoSize[i]++ - } - } - } - - s.TopologyNormalizingWeight = make([]float64, len(s.Constraints)) - for i, c := range s.Constraints { - sz := topoSize[i] - if c.TopologyKey == v1.LabelHostname { - sz = len(filteredNodes) - len(s.IgnoredNodes) - } - s.TopologyNormalizingWeight[i] = topologyNormalizingWeight(sz) - } - return nil -} - -// PreScore builds and writes cycle state used by Score and NormalizeScore. -func (pl *PodTopologySpread) PreScore( - ctx context.Context, - cycleState *framework.CycleState, - pod *v1.Pod, - filteredNodes []*framework.NodeInfo, -) *framework.Status { - allNodes, err := pl.sharedLister.NodeInfos().List() - if err != nil { - return framework.AsStatus(fmt.Errorf("getting all nodes: %w", err)) - } - - if len(allNodes) == 0 { - // No need to score. - return framework.NewStatus(framework.Skip) - } - - state := &preScoreState{ - IgnoredNodes: sets.New[string](), - } - // Only require that nodes have all the topology labels if using - // non-system-default spreading rules. This allows nodes that don't have a - // zone label to still have hostname spreading. - requireAllTopologies := len(pod.Spec.TopologySpreadConstraints) > 0 || !pl.systemDefaulted - err = pl.initPreScoreState(state, pod, filteredNodes, requireAllTopologies) - if err != nil { - return framework.AsStatus(fmt.Errorf("calculating preScoreState: %w", err)) - } - - // return Skip if incoming pod doesn't have soft topology spread Constraints. - if len(state.Constraints) == 0 { - return framework.NewStatus(framework.Skip) - } - - // Ignore parsing errors for backwards compatibility. - requiredNodeAffinity := nodeaffinity.GetRequiredNodeAffinity(pod) - processAllNode := func(n int) { - nodeInfo := allNodes[n] - node := nodeInfo.Node() - - if !pl.enableNodeInclusionPolicyInPodTopologySpread { - // `node` should satisfy incoming pod's NodeSelector/NodeAffinity - if match, _ := requiredNodeAffinity.Match(node); !match { - return - } - } - - // All topologyKeys need to be present in `node` - if requireAllTopologies && !nodeLabelsMatchSpreadConstraints(node.Labels, state.Constraints) { - return - } - - for i, c := range state.Constraints { - if pl.enableNodeInclusionPolicyInPodTopologySpread && - !c.matchNodeInclusionPolicies(pod, node, requiredNodeAffinity) { - continue - } - - value := node.Labels[c.TopologyKey] - // If current topology pair is not associated with any candidate node, - // continue to avoid unnecessary calculation. - // Per-node counts are also skipped, as they are done during Score. - tpCount := state.TopologyValueToPodCounts[i][value] - if tpCount == nil { - continue - } - count := countPodsMatchSelector(nodeInfo.Pods, c.Selector, pod.Namespace) - atomic.AddInt64(tpCount, int64(count)) - } - } - pl.parallelizer.Until(ctx, len(allNodes), processAllNode, pl.Name()) - - cycleState.Write(preScoreStateKey, state) - return nil -} - -// Score invoked at the Score extension point. -// The "score" returned in this function is the matching number of pods on the `nodeName`, -// it is normalized later. -func (pl *PodTopologySpread) Score(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - node := nodeInfo.Node() - s, err := getPreScoreState(cycleState) - if err != nil { - return 0, framework.AsStatus(err) - } - - // Return if the node is not qualified. - if s.IgnoredNodes.Has(node.Name) { - return 0, nil - } - - // For each present , current node gets a credit of . - // And we sum up and return it as this node's score. - var score float64 - for i, c := range s.Constraints { - if tpVal, ok := node.Labels[c.TopologyKey]; ok { - var cnt int64 - if c.TopologyKey == v1.LabelHostname { - cnt = int64(countPodsMatchSelector(nodeInfo.Pods, c.Selector, pod.Namespace)) - } else { - cnt = *s.TopologyValueToPodCounts[i][tpVal] - } - score += scoreForCount(cnt, c.MaxSkew, s.TopologyNormalizingWeight[i]) - } - } - return int64(math.Round(score)), nil -} - -// NormalizeScore invoked after scoring all nodes. -func (pl *PodTopologySpread) NormalizeScore(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status { - s, err := getPreScoreState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - if s == nil { - return nil - } - - // Calculate and - var minScore int64 = math.MaxInt64 - var maxScore int64 - for i, score := range scores { - // it's mandatory to check if is present in m.IgnoredNodes - if s.IgnoredNodes.Has(score.Name) { - scores[i].Score = invalidScore - continue - } - if score.Score < minScore { - minScore = score.Score - } - if score.Score > maxScore { - maxScore = score.Score - } - } - - for i := range scores { - if scores[i].Score == invalidScore { - scores[i].Score = 0 - continue - } - if maxScore == 0 { - scores[i].Score = framework.MaxNodeScore - continue - } - s := scores[i].Score - scores[i].Score = framework.MaxNodeScore * (maxScore + minScore - s) / maxScore - } - return nil -} - -// ScoreExtensions of the Score plugin. -func (pl *PodTopologySpread) ScoreExtensions() framework.ScoreExtensions { - return pl -} - -func getPreScoreState(cycleState *framework.CycleState) (*preScoreState, error) { - c, err := cycleState.Read(preScoreStateKey) - if err != nil { - return nil, fmt.Errorf("error reading %q from cycleState: %w", preScoreStateKey, err) - } - - s, ok := c.(*preScoreState) - if !ok { - return nil, fmt.Errorf("%+v convert to podtopologyspread.preScoreState error", c) - } - return s, nil -} - -// topologyNormalizingWeight calculates the weight for the topology, based on -// the number of values that exist for a topology. -// Since is at least 1 (all nodes that passed the Filters are in the -// same topology), and k8s supports 5k nodes, the result is in the interval -// <1.09, 8.52>. -// -// Note: could also be zero when no nodes have the required topologies, -// however we don't care about topology weight in this case as we return a 0 -// score for all nodes. -func topologyNormalizingWeight(size int) float64 { - return math.Log(float64(size + 2)) -} - -// scoreForCount calculates the score based on number of matching pods in a -// topology domain, the constraint's maxSkew and the topology weight. -// `maxSkew-1` is added to the score so that differences between topology -// domains get watered down, controlling the tolerance of the score to skews. -func scoreForCount(cnt int64, maxSkew int32, tpWeight float64) float64 { - return float64(cnt)*tpWeight + float64(maxSkew-1) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort/priority_sort.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort/priority_sort.go deleted file mode 100644 index b705cb738..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort/priority_sort.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package queuesort - -import ( - "context" - - "k8s.io/apimachinery/pkg/runtime" - corev1helpers "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" -) - -// Name is the name of the plugin used in the plugin registry and configurations. -const Name = names.PrioritySort - -// PrioritySort is a plugin that implements Priority based sorting. -type PrioritySort struct{} - -var _ framework.QueueSortPlugin = &PrioritySort{} - -// Name returns name of the plugin. -func (pl *PrioritySort) Name() string { - return Name -} - -// Less is the function used by the activeQ heap algorithm to sort pods. -// It sorts pods based on their priority. When priorities are equal, it uses -// PodQueueInfo.timestamp. -func (pl *PrioritySort) Less(pInfo1, pInfo2 *framework.QueuedPodInfo) bool { - p1 := corev1helpers.PodPriority(pInfo1.Pod) - p2 := corev1helpers.PodPriority(pInfo2.Pod) - return (p1 > p2) || (p1 == p2 && pInfo1.Timestamp.Before(pInfo2.Timestamp)) -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, handle framework.Handle) (framework.Plugin, error) { - return &PrioritySort{}, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go deleted file mode 100644 index 3e3f27092..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/registry.go +++ /dev/null @@ -1,89 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package plugins - -import ( - "k8s.io/apiserver/pkg/util/feature" - "k8s.io/kubernetes/pkg/features" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources" - plfeature "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone" - "k8s.io/kubernetes/pkg/scheduler/framework/runtime" -) - -// NewInTreeRegistry builds the registry with all the in-tree plugins. -// A scheduler that runs out of tree plugins can register additional plugins -// through the WithFrameworkOutOfTreeRegistry option. -func NewInTreeRegistry() runtime.Registry { - fts := plfeature.Features{ - EnableDRAPrioritizedList: feature.DefaultFeatureGate.Enabled(features.DRAPrioritizedList), - EnableDRAAdminAccess: feature.DefaultFeatureGate.Enabled(features.DRAAdminAccess), - EnableDRADeviceTaints: feature.DefaultFeatureGate.Enabled(features.DRADeviceTaints), - EnableDynamicResourceAllocation: feature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation), - EnableVolumeAttributesClass: feature.DefaultFeatureGate.Enabled(features.VolumeAttributesClass), - EnableCSIMigrationPortworx: feature.DefaultFeatureGate.Enabled(features.CSIMigrationPortworx), - EnableNodeInclusionPolicyInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.NodeInclusionPolicyInPodTopologySpread), - EnableMatchLabelKeysInPodTopologySpread: feature.DefaultFeatureGate.Enabled(features.MatchLabelKeysInPodTopologySpread), - EnableInPlacePodVerticalScaling: feature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling), - EnableSidecarContainers: feature.DefaultFeatureGate.Enabled(features.SidecarContainers), - EnableSchedulingQueueHint: feature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints), - EnableAsyncPreemption: feature.DefaultFeatureGate.Enabled(features.SchedulerAsyncPreemption), - EnablePodLevelResources: feature.DefaultFeatureGate.Enabled(features.PodLevelResources), - EnablePartitionableDevices: feature.DefaultFeatureGate.Enabled(features.DRAPartitionableDevices), - EnableStorageCapacityScoring: feature.DefaultFeatureGate.Enabled(features.StorageCapacityScoring), - } - - registry := runtime.Registry{ - dynamicresources.Name: runtime.FactoryAdapter(fts, dynamicresources.New), - imagelocality.Name: imagelocality.New, - tainttoleration.Name: runtime.FactoryAdapter(fts, tainttoleration.New), - nodename.Name: runtime.FactoryAdapter(fts, nodename.New), - nodeports.Name: runtime.FactoryAdapter(fts, nodeports.New), - nodeaffinity.Name: runtime.FactoryAdapter(fts, nodeaffinity.New), - podtopologyspread.Name: runtime.FactoryAdapter(fts, podtopologyspread.New), - nodeunschedulable.Name: runtime.FactoryAdapter(fts, nodeunschedulable.New), - noderesources.Name: runtime.FactoryAdapter(fts, noderesources.NewFit), - noderesources.BalancedAllocationName: runtime.FactoryAdapter(fts, noderesources.NewBalancedAllocation), - volumebinding.Name: runtime.FactoryAdapter(fts, volumebinding.New), - volumerestrictions.Name: runtime.FactoryAdapter(fts, volumerestrictions.New), - volumezone.Name: runtime.FactoryAdapter(fts, volumezone.New), - nodevolumelimits.CSIName: runtime.FactoryAdapter(fts, nodevolumelimits.NewCSI), - interpodaffinity.Name: runtime.FactoryAdapter(fts, interpodaffinity.New), - queuesort.Name: queuesort.New, - defaultbinder.Name: defaultbinder.New, - defaultpreemption.Name: runtime.FactoryAdapter(fts, defaultpreemption.New), - schedulinggates.Name: runtime.FactoryAdapter(fts, schedulinggates.New), - } - - return registry -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates/scheduling_gates.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates/scheduling_gates.go deleted file mode 100644 index bccd4bd8b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates/scheduling_gates.go +++ /dev/null @@ -1,94 +0,0 @@ -/* -Copyright 2022 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package schedulinggates - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/klog/v2" - - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// Name of the plugin used in the plugin registry and configurations. -const Name = names.SchedulingGates - -// SchedulingGates checks if a Pod carries .spec.schedulingGates. -type SchedulingGates struct { - enableSchedulingQueueHint bool -} - -var _ framework.PreEnqueuePlugin = &SchedulingGates{} -var _ framework.EnqueueExtensions = &SchedulingGates{} - -func (pl *SchedulingGates) Name() string { - return Name -} - -func (pl *SchedulingGates) PreEnqueue(ctx context.Context, p *v1.Pod) *framework.Status { - if len(p.Spec.SchedulingGates) == 0 { - return nil - } - gates := make([]string, 0, len(p.Spec.SchedulingGates)) - for _, gate := range p.Spec.SchedulingGates { - gates = append(gates, gate.Name) - } - return framework.NewStatus(framework.UnschedulableAndUnresolvable, fmt.Sprintf("waiting for scheduling gates: %v", gates)) -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *SchedulingGates) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - if !pl.enableSchedulingQueueHint { - return nil, nil - } - // When the QueueingHint feature is enabled, - // the scheduling queue uses Pod/Update Queueing Hint - // to determine whether a Pod's update makes the Pod schedulable or not. - // https://github.com/kubernetes/kubernetes/pull/122234 - return []framework.ClusterEventWithHint{ - // Pods can be more schedulable once it's gates are removed - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.UpdatePodSchedulingGatesEliminated}, QueueingHintFn: pl.isSchedulableAfterUpdatePodSchedulingGatesEliminated}, - }, nil -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, _ framework.Handle, fts feature.Features) (framework.Plugin, error) { - return &SchedulingGates{ - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - }, nil -} - -func (pl *SchedulingGates) isSchedulableAfterUpdatePodSchedulingGatesEliminated(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, modifiedPod, err := util.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - if modifiedPod.UID != pod.UID { - // If the update event is not for targetPod, it wouldn't make targetPod schedulable. - return framework.QueueSkip, nil - } - - return framework.Queue, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration/taint_toleration.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration/taint_toleration.go deleted file mode 100644 index 3eb8f5e1a..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration/taint_toleration.go +++ /dev/null @@ -1,229 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package tainttoleration - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - v1helper "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// TaintToleration is a plugin that checks if a pod tolerates a node's taints. -type TaintToleration struct { - handle framework.Handle - enableSchedulingQueueHint bool -} - -var _ framework.FilterPlugin = &TaintToleration{} -var _ framework.PreScorePlugin = &TaintToleration{} -var _ framework.ScorePlugin = &TaintToleration{} -var _ framework.EnqueueExtensions = &TaintToleration{} - -const ( - // Name is the name of the plugin used in the plugin registry and configurations. - Name = names.TaintToleration - // preScoreStateKey is the key in CycleState to TaintToleration pre-computed data for Scoring. - preScoreStateKey = "PreScore" + Name - // ErrReasonNotMatch is the Filter reason status when not matching. - ErrReasonNotMatch = "node(s) had taints that the pod didn't tolerate" -) - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *TaintToleration) Name() string { - return Name -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *TaintToleration) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - if pl.enableSchedulingQueueHint { - return []framework.ClusterEventWithHint{ - // When the QueueingHint feature is enabled, preCheck is eliminated and we don't need additional UpdateNodeLabel. - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.UpdateNodeTaint}, QueueingHintFn: pl.isSchedulableAfterNodeChange}, - // When the QueueingHint feature is enabled, - // the scheduling queue uses Pod/Update Queueing Hint - // to determine whether a Pod's update makes the Pod schedulable or not. - // https://github.com/kubernetes/kubernetes/pull/122234 - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.UpdatePodToleration}, QueueingHintFn: pl.isSchedulableAfterPodTolerationChange}, - }, nil - } - - return []framework.ClusterEventWithHint{ - // A note about UpdateNodeLabel event: - // Ideally, it's supposed to register only Add | UpdateNodeTaint because UpdateNodeLabel will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: framework.Add | framework.UpdateNodeTaint | framework.UpdateNodeLabel}, QueueingHintFn: pl.isSchedulableAfterNodeChange}, - // No need to register the Pod event; the update to the unschedulable Pods already triggers the scheduling retry when QHint is disabled. - }, nil -} - -// isSchedulableAfterNodeChange is invoked for all node events reported by -// an informer. It checks whether that change made a previously unschedulable -// pod schedulable. -func (pl *TaintToleration) isSchedulableAfterNodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalNode, modifiedNode, err := util.As[*v1.Node](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - wasUntolerated := true - if originalNode != nil { - _, wasUntolerated = v1helper.FindMatchingUntoleratedTaint(originalNode.Spec.Taints, pod.Spec.Tolerations, helper.DoNotScheduleTaintsFilterFunc()) - } - - _, isUntolerated := v1helper.FindMatchingUntoleratedTaint(modifiedNode.Spec.Taints, pod.Spec.Tolerations, helper.DoNotScheduleTaintsFilterFunc()) - - if wasUntolerated && !isUntolerated { - logger.V(5).Info("node was created or updated, and this may make the Pod rejected by TaintToleration plugin in the previous scheduling cycle schedulable", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.Queue, nil - } - - logger.V(5).Info("node was created or updated, but it doesn't change the TaintToleration plugin's decision", "pod", klog.KObj(pod), "node", klog.KObj(modifiedNode)) - return framework.QueueSkip, nil -} - -// Filter invoked at the filter extension point. -func (pl *TaintToleration) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - node := nodeInfo.Node() - - taint, isUntolerated := v1helper.FindMatchingUntoleratedTaint(node.Spec.Taints, pod.Spec.Tolerations, helper.DoNotScheduleTaintsFilterFunc()) - if !isUntolerated { - return nil - } - - errReason := fmt.Sprintf("node(s) had untolerated taint {%s: %s}", taint.Key, taint.Value) - return framework.NewStatus(framework.UnschedulableAndUnresolvable, errReason) -} - -// preScoreState computed at PreScore and used at Score. -type preScoreState struct { - tolerationsPreferNoSchedule []v1.Toleration -} - -// Clone implements the mandatory Clone interface. We don't really copy the data since -// there is no need for that. -func (s *preScoreState) Clone() framework.StateData { - return s -} - -// getAllTolerationEffectPreferNoSchedule gets the list of all Tolerations with Effect PreferNoSchedule or with no effect. -func getAllTolerationPreferNoSchedule(tolerations []v1.Toleration) (tolerationList []v1.Toleration) { - for _, toleration := range tolerations { - // Empty effect means all effects which includes PreferNoSchedule, so we need to collect it as well. - if len(toleration.Effect) == 0 || toleration.Effect == v1.TaintEffectPreferNoSchedule { - tolerationList = append(tolerationList, toleration) - } - } - return -} - -// PreScore builds and writes cycle state used by Score and NormalizeScore. -func (pl *TaintToleration) PreScore(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) *framework.Status { - tolerationsPreferNoSchedule := getAllTolerationPreferNoSchedule(pod.Spec.Tolerations) - state := &preScoreState{ - tolerationsPreferNoSchedule: tolerationsPreferNoSchedule, - } - cycleState.Write(preScoreStateKey, state) - return nil -} - -func getPreScoreState(cycleState *framework.CycleState) (*preScoreState, error) { - c, err := cycleState.Read(preScoreStateKey) - if err != nil { - return nil, fmt.Errorf("failed to read %q from cycleState: %w", preScoreStateKey, err) - } - - s, ok := c.(*preScoreState) - if !ok { - return nil, fmt.Errorf("%+v convert to tainttoleration.preScoreState error", c) - } - return s, nil -} - -// CountIntolerableTaintsPreferNoSchedule gives the count of intolerable taints of a pod with effect PreferNoSchedule -func countIntolerableTaintsPreferNoSchedule(taints []v1.Taint, tolerations []v1.Toleration) (intolerableTaints int) { - for _, taint := range taints { - // check only on taints that have effect PreferNoSchedule - if taint.Effect != v1.TaintEffectPreferNoSchedule { - continue - } - - if !v1helper.TolerationsTolerateTaint(tolerations, &taint) { - intolerableTaints++ - } - } - return -} - -// Score invoked at the Score extension point. -func (pl *TaintToleration) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - node := nodeInfo.Node() - - s, err := getPreScoreState(state) - if err != nil { - return 0, framework.AsStatus(err) - } - - score := int64(countIntolerableTaintsPreferNoSchedule(node.Spec.Taints, s.tolerationsPreferNoSchedule)) - return score, nil -} - -// NormalizeScore invoked after scoring all nodes. -func (pl *TaintToleration) NormalizeScore(ctx context.Context, _ *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status { - return helper.DefaultNormalizeScore(framework.MaxNodeScore, true, scores) -} - -// ScoreExtensions of the Score plugin. -func (pl *TaintToleration) ScoreExtensions() framework.ScoreExtensions { - return pl -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, h framework.Handle, fts feature.Features) (framework.Plugin, error) { - return &TaintToleration{ - handle: h, - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - }, nil -} - -// isSchedulableAfterPodTolerationChange is invoked whenever a pod's toleration changed. -func (pl *TaintToleration) isSchedulableAfterPodTolerationChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, modifiedPod, err := util.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - if pod.UID == modifiedPod.UID { - // The updated Pod is the unschedulable Pod. - logger.V(5).Info("a new toleration is added for the unschedulable Pod, and it may make it schedulable", "pod", klog.KObj(modifiedPod)) - return framework.Queue, nil - } - - logger.V(5).Info("a new toleration is added for a Pod, but it's an unrelated Pod and wouldn't change the TaintToleration plugin's decision", "pod", klog.KObj(modifiedPod)) - - return framework.QueueSkip, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/OWNERS b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/OWNERS deleted file mode 100644 index be3245e85..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - sig-storage-approvers - - cofyc -reviewers: - - sig-storage-reviewers - - cofyc -labels: - - sig/storage diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go deleted file mode 100644 index e12fb08a0..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/assume_cache.go +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumebinding - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - storagehelpers "k8s.io/component-helpers/storage/volume" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/util/assumecache" -) - -// PVAssumeCache is a AssumeCache for PersistentVolume objects -type PVAssumeCache struct { - *assumecache.AssumeCache - logger klog.Logger -} - -func pvStorageClassIndexFunc(obj interface{}) ([]string, error) { - if pv, ok := obj.(*v1.PersistentVolume); ok { - return []string{storagehelpers.GetPersistentVolumeClass(pv)}, nil - } - return []string{""}, fmt.Errorf("object is not a v1.PersistentVolume: %v", obj) -} - -// NewPVAssumeCache creates a PV assume cache. -func NewPVAssumeCache(logger klog.Logger, informer assumecache.Informer) *PVAssumeCache { - logger = klog.LoggerWithName(logger, "PV Cache") - return &PVAssumeCache{ - AssumeCache: assumecache.NewAssumeCache(logger, informer, "v1.PersistentVolume", "storageclass", pvStorageClassIndexFunc), - logger: logger, - } -} - -func (c *PVAssumeCache) GetPV(pvName string) (*v1.PersistentVolume, error) { - obj, err := c.Get(pvName) - if err != nil { - return nil, err - } - - pv, ok := obj.(*v1.PersistentVolume) - if !ok { - return nil, &assumecache.WrongTypeError{TypeName: "v1.PersistentVolume", Object: obj} - } - return pv, nil -} - -func (c *PVAssumeCache) GetAPIPV(pvName string) (*v1.PersistentVolume, error) { - obj, err := c.GetAPIObj(pvName) - if err != nil { - return nil, err - } - pv, ok := obj.(*v1.PersistentVolume) - if !ok { - return nil, &assumecache.WrongTypeError{TypeName: "v1.PersistentVolume", Object: obj} - } - return pv, nil -} - -func (c *PVAssumeCache) ListPVs(storageClassName string) []*v1.PersistentVolume { - objs := c.List(&v1.PersistentVolume{ - Spec: v1.PersistentVolumeSpec{ - StorageClassName: storageClassName, - }, - }) - pvs := []*v1.PersistentVolume{} - for _, obj := range objs { - pv, ok := obj.(*v1.PersistentVolume) - if !ok { - c.logger.Error(&assumecache.WrongTypeError{TypeName: "v1.PersistentVolume", Object: obj}, "ListPVs") - continue - } - pvs = append(pvs, pv) - } - return pvs -} - -// PVCAssumeCache is a AssumeCache for PersistentVolumeClaim objects -type PVCAssumeCache struct { - *assumecache.AssumeCache - logger klog.Logger -} - -// NewPVCAssumeCache creates a PVC assume cache. -func NewPVCAssumeCache(logger klog.Logger, informer assumecache.Informer) *PVCAssumeCache { - logger = klog.LoggerWithName(logger, "PVC Cache") - return &PVCAssumeCache{ - AssumeCache: assumecache.NewAssumeCache(logger, informer, "v1.PersistentVolumeClaim", "", nil), - logger: logger, - } -} - -func (c *PVCAssumeCache) GetPVC(pvcKey string) (*v1.PersistentVolumeClaim, error) { - obj, err := c.Get(pvcKey) - if err != nil { - return nil, err - } - - pvc, ok := obj.(*v1.PersistentVolumeClaim) - if !ok { - return nil, &assumecache.WrongTypeError{TypeName: "v1.PersistentVolumeClaim", Object: obj} - } - return pvc, nil -} - -func (c *PVCAssumeCache) GetAPIPVC(pvcKey string) (*v1.PersistentVolumeClaim, error) { - obj, err := c.GetAPIObj(pvcKey) - if err != nil { - return nil, err - } - pvc, ok := obj.(*v1.PersistentVolumeClaim) - if !ok { - return nil, &assumecache.WrongTypeError{TypeName: "v1.PersistentVolumeClaim", Object: obj} - } - return pvc, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go deleted file mode 100644 index 783d65889..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/binder.go +++ /dev/null @@ -1,1124 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumebinding - -import ( - "context" - "errors" - "fmt" - "sort" - "strings" - "time" - - v1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/apiserver/pkg/storage" - coreinformers "k8s.io/client-go/informers/core/v1" - storageinformers "k8s.io/client-go/informers/storage/v1" - clientset "k8s.io/client-go/kubernetes" - corelisters "k8s.io/client-go/listers/core/v1" - storagelisters "k8s.io/client-go/listers/storage/v1" - "k8s.io/component-helpers/storage/ephemeral" - "k8s.io/component-helpers/storage/volume" - csitrans "k8s.io/csi-translation-lib" - csiplugins "k8s.io/csi-translation-lib/plugins" - "k8s.io/klog/v2" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics" - "k8s.io/kubernetes/pkg/scheduler/util/assumecache" -) - -// ConflictReason is used for the special strings which explain why -// volume binding is impossible for a node. -type ConflictReason string - -// ConflictReasons contains all reasons that explain why volume binding is impossible for a node. -type ConflictReasons []ConflictReason - -func (reasons ConflictReasons) Len() int { return len(reasons) } -func (reasons ConflictReasons) Less(i, j int) bool { return reasons[i] < reasons[j] } -func (reasons ConflictReasons) Swap(i, j int) { reasons[i], reasons[j] = reasons[j], reasons[i] } - -const ( - // ErrReasonBindConflict is used for VolumeBindingNoMatch predicate error. - ErrReasonBindConflict ConflictReason = "node(s) didn't find available persistent volumes to bind" - // ErrReasonNodeConflict is used for VolumeNodeAffinityConflict predicate error. - ErrReasonNodeConflict ConflictReason = "node(s) didn't match PersistentVolume's node affinity" - // ErrReasonNotEnoughSpace is used when a pod cannot start on a node because not enough storage space is available. - ErrReasonNotEnoughSpace = "node(s) did not have enough free storage" - // ErrReasonPVNotExist is used when a pod has one or more PVC(s) bound to non-existent persistent volume(s)" - ErrReasonPVNotExist = "node(s) unavailable due to one or more pvc(s) bound to non-existent pv(s)" -) - -// BindingInfo holds a binding between PV and PVC. -type BindingInfo struct { - // PVC that needs to be bound - pvc *v1.PersistentVolumeClaim - - // Proposed PV to bind to this PVC - pv *v1.PersistentVolume -} - -// StorageClassName returns the name of the storage class. -func (b *BindingInfo) StorageClassName() string { - return b.pv.Spec.StorageClassName -} - -// StorageResource represents storage resource. -type StorageResource struct { - Requested int64 - Capacity int64 -} - -// StorageResource returns storage resource. -func (b *BindingInfo) StorageResource() *StorageResource { - // both fields are mandatory - requestedQty := b.pvc.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] - capacityQty := b.pv.Spec.Capacity[v1.ResourceName(v1.ResourceStorage)] - return &StorageResource{ - Requested: requestedQty.Value(), - Capacity: capacityQty.Value(), - } -} - -// DynamicProvision represents a dynamically provisioned volume. -type DynamicProvision struct { - PVC *v1.PersistentVolumeClaim - NodeCapacity *storagev1.CSIStorageCapacity -} - -// PodVolumes holds pod's volumes information used in volume scheduling. -type PodVolumes struct { - // StaticBindings are binding decisions for PVCs which can be bound to - // pre-provisioned static PVs. - StaticBindings []*BindingInfo - // DynamicProvisions are PVCs that require dynamic provisioning - DynamicProvisions []*DynamicProvision -} - -// InTreeToCSITranslator contains methods required to check migratable status -// and perform translations from InTree PV's to CSI -type InTreeToCSITranslator interface { - IsPVMigratable(pv *v1.PersistentVolume) bool - GetInTreePluginNameFromSpec(pv *v1.PersistentVolume, vol *v1.Volume) (string, error) - TranslateInTreePVToCSI(logger klog.Logger, pv *v1.PersistentVolume) (*v1.PersistentVolume, error) -} - -// SchedulerVolumeBinder is used by the scheduler VolumeBinding plugin to -// handle PVC/PV binding and dynamic provisioning. The binding decisions are -// integrated into the pod scheduling workflow so that the PV NodeAffinity is -// also considered along with the pod's other scheduling requirements. -// -// This integrates into the existing scheduler workflow as follows: -// 1. The scheduler takes a Pod off the scheduler queue and processes it serially: -// a. Invokes all pre-filter plugins for the pod. GetPodVolumeClaims() is invoked -// here, pod volume information will be saved in current scheduling cycle state for later use. -// b. Invokes all filter plugins, parallelized across nodes. FindPodVolumes() is invoked here. -// c. Invokes all score plugins. Future/TBD -// d. Selects the best node for the Pod. -// e. Invokes all reserve plugins. AssumePodVolumes() is invoked here. -// i. If PVC binding is required, cache in-memory only: -// * For manual binding: update PV objects for prebinding to the corresponding PVCs. -// * For dynamic provisioning: update PVC object with a selected node from c) -// * For the pod, which PVCs and PVs need API updates. -// ii. Afterwards, the main scheduler caches the Pod->Node binding in the scheduler's pod cache, -// This is handled in the scheduler and not here. -// f. Asynchronously bind volumes and pod in a separate goroutine -// i. BindPodVolumes() is called first in PreBind phase. It makes all the necessary API updates and waits for -// PV controller to fully bind and provision the PVCs. If binding fails, the Pod is sent -// back through the scheduler. -// ii. After BindPodVolumes() is complete, then the scheduler does the final Pod->Node binding. -// 2. Once all the assume operations are done in e), the scheduler processes the next Pod in the scheduler queue -// while the actual binding operation occurs in the background. -type SchedulerVolumeBinder interface { - // GetPodVolumeClaims returns a pod's PVCs separated into bound, unbound with delayed binding (including provisioning), - // unbound with immediate binding (including prebound) and PVs that belong to storage classes of unbound PVCs with delayed binding. - GetPodVolumeClaims(logger klog.Logger, pod *v1.Pod) (podVolumeClaims *PodVolumeClaims, err error) - - // FindPodVolumes checks if all of a Pod's PVCs can be satisfied by the - // node and returns pod's volumes information. - // - // If a PVC is bound, it checks if the PV's NodeAffinity matches the Node. - // Otherwise, it tries to find an available PV to bind to the PVC. - // - // It returns an error when something went wrong or a list of reasons why the node is - // (currently) not usable for the pod. - // - // If the CSIStorageCapacity feature is enabled, then it also checks for sufficient storage - // for volumes that still need to be created. - // - // This function is called by the scheduler VolumeBinding plugin and can be called in parallel - FindPodVolumes(logger klog.Logger, pod *v1.Pod, podVolumeClaims *PodVolumeClaims, node *v1.Node) (podVolumes *PodVolumes, reasons ConflictReasons, err error) - - // AssumePodVolumes will: - // 1. Take the PV matches for unbound PVCs and update the PV cache assuming - // that the PV is prebound to the PVC. - // 2. Take the PVCs that need provisioning and update the PVC cache with related - // annotations set. - // - // It returns true if all volumes are fully bound - // - // This function is called serially. - AssumePodVolumes(logger klog.Logger, assumedPod *v1.Pod, nodeName string, podVolumes *PodVolumes) (allFullyBound bool, err error) - - // RevertAssumedPodVolumes will revert assumed PV and PVC cache. - RevertAssumedPodVolumes(podVolumes *PodVolumes) - - // BindPodVolumes will: - // 1. Initiate the volume binding by making the API call to prebind the PV - // to its matching PVC. - // 2. Trigger the volume provisioning by making the API call to set related - // annotations on the PVC - // 3. Wait for PVCs to be completely bound by the PV controller - // - // This function can be called in parallel. - BindPodVolumes(ctx context.Context, assumedPod *v1.Pod, podVolumes *PodVolumes) error -} - -type PodVolumeClaims struct { - // boundClaims are the pod's bound PVCs. - boundClaims []*v1.PersistentVolumeClaim - // unboundClaimsDelayBinding are the pod's unbound with delayed binding (including provisioning) PVCs. - unboundClaimsDelayBinding []*v1.PersistentVolumeClaim - // unboundClaimsImmediate are the pod's unbound with immediate binding PVCs (i.e., supposed to be bound already) . - unboundClaimsImmediate []*v1.PersistentVolumeClaim - // unboundVolumesDelayBinding are PVs that belong to storage classes of the pod's unbound PVCs with delayed binding. - unboundVolumesDelayBinding map[string][]*v1.PersistentVolume -} - -type volumeBinder struct { - kubeClient clientset.Interface - enableVolumeAttributesClass bool - enableCSIMigrationPortworx bool - - classLister storagelisters.StorageClassLister - podLister corelisters.PodLister - nodeLister corelisters.NodeLister - csiNodeLister storagelisters.CSINodeLister - - pvcCache *PVCAssumeCache - pvCache *PVAssumeCache - - // Amount of time to wait for the bind operation to succeed - bindTimeout time.Duration - - translator InTreeToCSITranslator - - csiDriverLister storagelisters.CSIDriverLister - csiStorageCapacityLister storagelisters.CSIStorageCapacityLister -} - -var _ SchedulerVolumeBinder = &volumeBinder{} - -// CapacityCheck contains additional parameters for NewVolumeBinder that -// are only needed when checking volume sizes against available storage -// capacity is desired. -type CapacityCheck struct { - CSIDriverInformer storageinformers.CSIDriverInformer - CSIStorageCapacityInformer storageinformers.CSIStorageCapacityInformer -} - -// NewVolumeBinder sets up all the caches needed for the scheduler to make volume binding decisions. -// -// capacityCheck determines how storage capacity is checked (CSIStorageCapacity feature). -func NewVolumeBinder( - logger klog.Logger, - kubeClient clientset.Interface, - fts feature.Features, - podInformer coreinformers.PodInformer, - nodeInformer coreinformers.NodeInformer, - csiNodeInformer storageinformers.CSINodeInformer, - pvcInformer coreinformers.PersistentVolumeClaimInformer, - pvInformer coreinformers.PersistentVolumeInformer, - storageClassInformer storageinformers.StorageClassInformer, - capacityCheck CapacityCheck, - bindTimeout time.Duration) SchedulerVolumeBinder { - b := &volumeBinder{ - kubeClient: kubeClient, - enableVolumeAttributesClass: fts.EnableVolumeAttributesClass, - enableCSIMigrationPortworx: fts.EnableCSIMigrationPortworx, - podLister: podInformer.Lister(), - classLister: storageClassInformer.Lister(), - nodeLister: nodeInformer.Lister(), - csiNodeLister: csiNodeInformer.Lister(), - pvcCache: NewPVCAssumeCache(logger, pvcInformer.Informer()), - pvCache: NewPVAssumeCache(logger, pvInformer.Informer()), - bindTimeout: bindTimeout, - translator: csitrans.New(), - } - - b.csiDriverLister = capacityCheck.CSIDriverInformer.Lister() - b.csiStorageCapacityLister = capacityCheck.CSIStorageCapacityInformer.Lister() - - return b -} - -// FindPodVolumes finds the matching PVs for PVCs and nodes to provision PVs -// for the given pod and node. If the node does not fit, conflict reasons are -// returned. -func (b *volumeBinder) FindPodVolumes(logger klog.Logger, pod *v1.Pod, podVolumeClaims *PodVolumeClaims, node *v1.Node) (podVolumes *PodVolumes, reasons ConflictReasons, err error) { - podVolumes = &PodVolumes{} - - // Warning: Below log needs high verbosity as it can be printed several times (#60933). - logger.V(5).Info("FindPodVolumes", "pod", klog.KObj(pod), "node", klog.KObj(node)) - - // Initialize to true for pods that don't have volumes. These - // booleans get translated into reason strings when the function - // returns without an error. - unboundVolumesSatisfied := true - boundVolumesSatisfied := true - sufficientStorage := true - boundPVsFound := true - defer func() { - if err != nil { - return - } - if !boundVolumesSatisfied { - reasons = append(reasons, ErrReasonNodeConflict) - } - if !unboundVolumesSatisfied { - reasons = append(reasons, ErrReasonBindConflict) - } - if !sufficientStorage { - reasons = append(reasons, ErrReasonNotEnoughSpace) - } - if !boundPVsFound { - reasons = append(reasons, ErrReasonPVNotExist) - } - }() - - defer func() { - if err != nil { - metrics.VolumeSchedulingStageFailed.WithLabelValues("predicate").Inc() - } - }() - - var ( - staticBindings []*BindingInfo - dynamicProvisions []*DynamicProvision - ) - defer func() { - // Although we do not distinguish nil from empty in this function, for - // easier testing, we normalize empty to nil. - if len(staticBindings) == 0 { - staticBindings = nil - } - if len(dynamicProvisions) == 0 { - dynamicProvisions = nil - } - podVolumes.StaticBindings = staticBindings - podVolumes.DynamicProvisions = dynamicProvisions - }() - - // Check PV node affinity on bound volumes - if len(podVolumeClaims.boundClaims) > 0 { - boundVolumesSatisfied, boundPVsFound, err = b.checkBoundClaims(logger, podVolumeClaims.boundClaims, node, pod) - if err != nil { - return - } - } - - // Find matching volumes and node for unbound claims - if len(podVolumeClaims.unboundClaimsDelayBinding) > 0 { - var ( - claimsToFindMatching []*v1.PersistentVolumeClaim - claimsToProvision []*v1.PersistentVolumeClaim - ) - - // Filter out claims to provision - for _, claim := range podVolumeClaims.unboundClaimsDelayBinding { - if selectedNode, ok := claim.Annotations[volume.AnnSelectedNode]; ok { - if selectedNode != node.Name { - // Fast path, skip unmatched node. - unboundVolumesSatisfied = false - return - } - claimsToProvision = append(claimsToProvision, claim) - } else { - claimsToFindMatching = append(claimsToFindMatching, claim) - } - } - - // Find matching volumes - if len(claimsToFindMatching) > 0 { - var unboundClaims []*v1.PersistentVolumeClaim - unboundVolumesSatisfied, staticBindings, unboundClaims, err = b.findMatchingVolumes(logger, pod, claimsToFindMatching, podVolumeClaims.unboundVolumesDelayBinding, node) - if err != nil { - return - } - claimsToProvision = append(claimsToProvision, unboundClaims...) - } - - // Check for claims to provision. This is the first time where we potentially - // find out that storage is not sufficient for the node. - if len(claimsToProvision) > 0 { - unboundVolumesSatisfied, sufficientStorage, dynamicProvisions, err = b.checkVolumeProvisions(logger, pod, claimsToProvision, node) - if err != nil { - return - } - } - } - - return -} - -// ConvertDynamicProvisionsToPVCs converts a slice of *DynamicProvision to a -// slice of PersistentVolumeClaim -func convertDynamicProvisionsToPVCs(dynamicProvisions []*DynamicProvision) []*v1.PersistentVolumeClaim { - pvcs := make([]*v1.PersistentVolumeClaim, 0, len(dynamicProvisions)) - for _, dynamicProvision := range dynamicProvisions { - pvcs = append(pvcs, dynamicProvision.PVC) - } - return pvcs -} - -// AssumePodVolumes will take the matching PVs and PVCs to provision in pod's -// volume information for the chosen node, and: -// 1. Update the pvCache with the new prebound PV. -// 2. Update the pvcCache with the new PVCs with annotations set -// 3. Update PodVolumes again with cached API updates for PVs and PVCs. -func (b *volumeBinder) AssumePodVolumes(logger klog.Logger, assumedPod *v1.Pod, nodeName string, podVolumes *PodVolumes) (allFullyBound bool, err error) { - logger.V(4).Info("AssumePodVolumes", "pod", klog.KObj(assumedPod), "node", klog.KRef("", nodeName)) - defer func() { - if err != nil { - metrics.VolumeSchedulingStageFailed.WithLabelValues("assume").Inc() - } - }() - - if allBound := b.arePodVolumesBound(logger, assumedPod); allBound { - logger.V(4).Info("AssumePodVolumes: all PVCs bound and nothing to do", "pod", klog.KObj(assumedPod), "node", klog.KRef("", nodeName)) - return true, nil - } - - // Assume PV - newBindings := []*BindingInfo{} - for _, binding := range podVolumes.StaticBindings { - newPV, dirty, err := volume.GetBindVolumeToClaim(binding.pv, binding.pvc) - logger.V(5).Info("AssumePodVolumes: GetBindVolumeToClaim", - "pod", klog.KObj(assumedPod), - "PV", klog.KObj(binding.pv), - "PVC", klog.KObj(binding.pvc), - "newPV", klog.KObj(newPV), - "dirty", dirty, - ) - if err != nil { - logger.Error(err, "AssumePodVolumes: fail to GetBindVolumeToClaim") - b.revertAssumedPVs(newBindings) - return false, err - } - // TODO: can we assume every time? - if dirty { - err = b.pvCache.Assume(newPV) - if err != nil { - b.revertAssumedPVs(newBindings) - return false, err - } - } - newBindings = append(newBindings, &BindingInfo{pv: newPV, pvc: binding.pvc}) - } - - // Assume PVCs - newProvisionedPVCs := []*DynamicProvision{} - for _, dynamicProvision := range podVolumes.DynamicProvisions { - // The claims from method args can be pointing to watcher cache. We must not - // modify these, therefore create a copy. - claimClone := dynamicProvision.PVC.DeepCopy() - metav1.SetMetaDataAnnotation(&claimClone.ObjectMeta, volume.AnnSelectedNode, nodeName) - err = b.pvcCache.Assume(claimClone) - if err != nil { - pvcs := convertDynamicProvisionsToPVCs(newProvisionedPVCs) - b.revertAssumedPVs(newBindings) - b.revertAssumedPVCs(pvcs) - return - } - - newProvisionedPVCs = append(newProvisionedPVCs, &DynamicProvision{PVC: claimClone}) - } - - podVolumes.StaticBindings = newBindings - podVolumes.DynamicProvisions = newProvisionedPVCs - return -} - -// RevertAssumedPodVolumes will revert assumed PV and PVC cache. -func (b *volumeBinder) RevertAssumedPodVolumes(podVolumes *PodVolumes) { - pvcs := convertDynamicProvisionsToPVCs(podVolumes.DynamicProvisions) - b.revertAssumedPVs(podVolumes.StaticBindings) - b.revertAssumedPVCs(pvcs) -} - -// BindPodVolumes gets the cached bindings and PVCs to provision in pod's volumes information, -// makes the API update for those PVs/PVCs, and waits for the PVCs to be completely bound -// by the PV controller. -func (b *volumeBinder) BindPodVolumes(ctx context.Context, assumedPod *v1.Pod, podVolumes *PodVolumes) (err error) { - logger := klog.FromContext(ctx) - logger.V(4).Info("BindPodVolumes", "pod", klog.KObj(assumedPod), "node", klog.KRef("", assumedPod.Spec.NodeName)) - - defer func() { - if err != nil { - metrics.VolumeSchedulingStageFailed.WithLabelValues("bind").Inc() - } - }() - - bindings := podVolumes.StaticBindings - claimsToProvision := convertDynamicProvisionsToPVCs(podVolumes.DynamicProvisions) - - // Start API operations - err = b.bindAPIUpdate(ctx, assumedPod, bindings, claimsToProvision) - if err != nil { - return err - } - - err = wait.PollUntilContextTimeout(ctx, time.Second, b.bindTimeout, false, func(ctx context.Context) (bool, error) { - b, err := b.checkBindings(logger, assumedPod, bindings, claimsToProvision) - return b, err - }) - if err != nil { - return fmt.Errorf("binding volumes: %w", err) - } - return nil -} - -func getPodName(pod *v1.Pod) string { - return pod.Namespace + "/" + pod.Name -} - -func getPVCName(pvc *v1.PersistentVolumeClaim) string { - return pvc.Namespace + "/" + pvc.Name -} - -// bindAPIUpdate makes the API update for those PVs/PVCs. -func (b *volumeBinder) bindAPIUpdate(ctx context.Context, pod *v1.Pod, bindings []*BindingInfo, claimsToProvision []*v1.PersistentVolumeClaim) error { - logger := klog.FromContext(ctx) - podName := getPodName(pod) - if bindings == nil { - return fmt.Errorf("failed to get cached bindings for pod %q", podName) - } - if claimsToProvision == nil { - return fmt.Errorf("failed to get cached claims to provision for pod %q", podName) - } - - lastProcessedBinding := 0 - lastProcessedProvisioning := 0 - defer func() { - // only revert assumed cached updates for volumes we haven't successfully bound - if lastProcessedBinding < len(bindings) { - b.revertAssumedPVs(bindings[lastProcessedBinding:]) - } - // only revert assumed cached updates for claims we haven't updated, - if lastProcessedProvisioning < len(claimsToProvision) { - b.revertAssumedPVCs(claimsToProvision[lastProcessedProvisioning:]) - } - }() - - var ( - binding *BindingInfo - i int - claim *v1.PersistentVolumeClaim - ) - - // Do the actual prebinding. Let the PV controller take care of the rest - // There is no API rollback if the actual binding fails - for _, binding = range bindings { - // TODO: does it hurt if we make an api call and nothing needs to be updated? - logger.V(5).Info("Updating PersistentVolume: binding to claim", "pod", klog.KObj(pod), "PV", klog.KObj(binding.pv), "PVC", klog.KObj(binding.pvc)) - newPV, err := b.kubeClient.CoreV1().PersistentVolumes().Update(ctx, binding.pv, metav1.UpdateOptions{}) - if err != nil { - logger.V(4).Info("Updating PersistentVolume: binding to claim failed", "pod", klog.KObj(pod), "PV", klog.KObj(binding.pv), "PVC", klog.KObj(binding.pvc), "err", err) - return err - } - - logger.V(2).Info("Updated PersistentVolume with claim. Waiting for binding to complete", "pod", klog.KObj(pod), "PV", klog.KObj(binding.pv), "PVC", klog.KObj(binding.pvc)) - // Save updated object from apiserver for later checking. - binding.pv = newPV - lastProcessedBinding++ - } - - // Update claims objects to trigger volume provisioning. Let the PV controller take care of the rest - // PV controller is expected to signal back by removing related annotations if actual provisioning fails - for i, claim = range claimsToProvision { - logger.V(5).Info("Updating claims objects to trigger volume provisioning", "pod", klog.KObj(pod), "PVC", klog.KObj(claim)) - newClaim, err := b.kubeClient.CoreV1().PersistentVolumeClaims(claim.Namespace).Update(ctx, claim, metav1.UpdateOptions{}) - if err != nil { - logger.V(4).Info("Updating PersistentVolumeClaim: binding to volume failed", "PVC", klog.KObj(claim), "err", err) - return err - } - - // Save updated object from apiserver for later checking. - claimsToProvision[i] = newClaim - lastProcessedProvisioning++ - } - - return nil -} - -var ( - versioner = storage.APIObjectVersioner{} -) - -// checkBindings runs through all the PVCs in the Pod and checks: -// * if the PVC is fully bound -// * if there are any conditions that require binding to fail and be retried -// -// It returns true when all of the Pod's PVCs are fully bound, and error if -// binding (and scheduling) needs to be retried -// Note that it checks on API objects not PV/PVC cache, this is because -// PV/PVC cache can be assumed again in main scheduler loop, we must check -// latest state in API server which are shared with PV controller and -// provisioners -func (b *volumeBinder) checkBindings(logger klog.Logger, pod *v1.Pod, bindings []*BindingInfo, claimsToProvision []*v1.PersistentVolumeClaim) (bool, error) { - podName := getPodName(pod) - if bindings == nil { - return false, fmt.Errorf("failed to get cached bindings for pod %q", podName) - } - if claimsToProvision == nil { - return false, fmt.Errorf("failed to get cached claims to provision for pod %q", podName) - } - - node, err := b.nodeLister.Get(pod.Spec.NodeName) - if err != nil { - return false, fmt.Errorf("failed to get node %q: %w", pod.Spec.NodeName, err) - } - - csiNode, err := b.csiNodeLister.Get(node.Name) - if err != nil { - // TODO: return the error once CSINode is created by default - logger.V(4).Info("Could not get a CSINode object for the node", "node", klog.KObj(node), "err", err) - } - - // Check for any conditions that might require scheduling retry - - // When pod is deleted, binding operation should be cancelled. There is no - // need to check PV/PVC bindings any more. - _, err = b.podLister.Pods(pod.Namespace).Get(pod.Name) - if err != nil { - if apierrors.IsNotFound(err) { - return false, fmt.Errorf("pod does not exist any more: %w", err) - } - logger.Error(err, "Failed to get pod from the lister", "pod", klog.KObj(pod)) - } - - for _, binding := range bindings { - pv, err := b.pvCache.GetAPIPV(binding.pv.Name) - if err != nil { - return false, fmt.Errorf("failed to check binding: %w", err) - } - - pvc, err := b.pvcCache.GetAPIPVC(getPVCName(binding.pvc)) - if err != nil { - return false, fmt.Errorf("failed to check binding: %w", err) - } - - // Because we updated PV in apiserver, skip if API object is older - // and wait for new API object propagated from apiserver. - if versioner.CompareResourceVersion(binding.pv, pv) > 0 { - return false, nil - } - - pv, err = b.tryTranslatePVToCSI(logger, pv, csiNode) - if err != nil { - return false, fmt.Errorf("failed to translate pv to csi: %w", err) - } - - // Check PV's node affinity (the node might not have the proper label) - if err := volume.CheckNodeAffinity(pv, node.Labels); err != nil { - return false, fmt.Errorf("pv %q node affinity doesn't match node %q: %w", pv.Name, node.Name, err) - } - - // Check if pv.ClaimRef got dropped by unbindVolume() - if pv.Spec.ClaimRef == nil || pv.Spec.ClaimRef.UID == "" { - return false, fmt.Errorf("ClaimRef got reset for pv %q", pv.Name) - } - - // Check if pvc is fully bound - if !b.isPVCFullyBound(pvc) { - return false, nil - } - } - - for _, claim := range claimsToProvision { - pvc, err := b.pvcCache.GetAPIPVC(getPVCName(claim)) - if err != nil { - return false, fmt.Errorf("failed to check provisioning pvc: %w", err) - } - - // Because we updated PVC in apiserver, skip if API object is older - // and wait for new API object propagated from apiserver. - if versioner.CompareResourceVersion(claim, pvc) > 0 { - return false, nil - } - - // Check if selectedNode annotation is still set - if pvc.Annotations == nil { - return false, fmt.Errorf("selectedNode annotation reset for PVC %q", pvc.Name) - } - selectedNode := pvc.Annotations[volume.AnnSelectedNode] - if selectedNode != pod.Spec.NodeName { - // If provisioner fails to provision a volume, selectedNode - // annotation will be removed to signal back to the scheduler to - // retry. - return false, fmt.Errorf("provisioning failed for PVC %q", pvc.Name) - } - - // If the PVC is bound to a PV, check its node affinity - if pvc.Spec.VolumeName != "" { - pv, err := b.pvCache.GetAPIPV(pvc.Spec.VolumeName) - if err != nil { - if errors.Is(err, assumecache.ErrNotFound) { - // We tolerate NotFound error here, because PV is possibly - // not found because of API delay, we can check next time. - // And if PV does not exist because it's deleted, PVC will - // be unbound eventually. - return false, nil - } - return false, fmt.Errorf("failed to get pv %q from cache: %w", pvc.Spec.VolumeName, err) - } - - pv, err = b.tryTranslatePVToCSI(logger, pv, csiNode) - if err != nil { - return false, err - } - - if err := volume.CheckNodeAffinity(pv, node.Labels); err != nil { - return false, fmt.Errorf("pv %q node affinity doesn't match node %q: %w", pv.Name, node.Name, err) - } - } - - // Check if pvc is fully bound - if !b.isPVCFullyBound(pvc) { - return false, nil - } - } - - // All pvs and pvcs that we operated on are bound - logger.V(2).Info("All PVCs for pod are bound", "pod", klog.KObj(pod)) - return true, nil -} - -func (b *volumeBinder) isVolumeBound(logger klog.Logger, pod *v1.Pod, vol *v1.Volume) (bound bool, pvc *v1.PersistentVolumeClaim, err error) { - pvcName := "" - isEphemeral := false - switch { - case vol.PersistentVolumeClaim != nil: - pvcName = vol.PersistentVolumeClaim.ClaimName - case vol.Ephemeral != nil: - // Generic ephemeral inline volumes also use a PVC, - // just with a computed name, and... - pvcName = ephemeral.VolumeClaimName(pod, vol) - isEphemeral = true - default: - return true, nil, nil - } - - bound, pvc, err = b.isPVCBound(logger, pod.Namespace, pvcName) - // ... the PVC must be owned by the pod. - if isEphemeral && err == nil && pvc != nil { - if err := ephemeral.VolumeIsForPod(pod, pvc); err != nil { - return false, nil, err - } - } - return -} - -func (b *volumeBinder) isPVCBound(logger klog.Logger, namespace, pvcName string) (bool, *v1.PersistentVolumeClaim, error) { - claim := &v1.PersistentVolumeClaim{ - ObjectMeta: metav1.ObjectMeta{ - Name: pvcName, - Namespace: namespace, - }, - } - pvcKey := getPVCName(claim) - pvc, err := b.pvcCache.GetPVC(pvcKey) - if err != nil || pvc == nil { - return false, nil, fmt.Errorf("error getting PVC %q: %v", pvcKey, err) - } - - fullyBound := b.isPVCFullyBound(pvc) - if fullyBound { - logger.V(5).Info("PVC is fully bound to PV", "PVC", klog.KObj(pvc), "PV", klog.KRef("", pvc.Spec.VolumeName)) - } else { - if pvc.Spec.VolumeName != "" { - logger.V(5).Info("PVC is not fully bound to PV", "PVC", klog.KObj(pvc), "PV", klog.KRef("", pvc.Spec.VolumeName)) - } else { - logger.V(5).Info("PVC is not bound", "PVC", klog.KObj(pvc)) - } - } - return fullyBound, pvc, nil -} - -func (b *volumeBinder) isPVCFullyBound(pvc *v1.PersistentVolumeClaim) bool { - return pvc.Spec.VolumeName != "" && metav1.HasAnnotation(pvc.ObjectMeta, volume.AnnBindCompleted) -} - -// arePodVolumesBound returns true if all volumes are fully bound -func (b *volumeBinder) arePodVolumesBound(logger klog.Logger, pod *v1.Pod) bool { - for _, vol := range pod.Spec.Volumes { - if isBound, _, _ := b.isVolumeBound(logger, pod, &vol); !isBound { - // Pod has at least one PVC that needs binding - return false - } - } - return true -} - -// GetPodVolumeClaims returns a pod's PVCs separated into bound, unbound with delayed binding (including provisioning), -// unbound with immediate binding (including prebound) and PVs that belong to storage classes of unbound PVCs with delayed binding. -func (b *volumeBinder) GetPodVolumeClaims(logger klog.Logger, pod *v1.Pod) (podVolumeClaims *PodVolumeClaims, err error) { - podVolumeClaims = &PodVolumeClaims{ - boundClaims: []*v1.PersistentVolumeClaim{}, - unboundClaimsImmediate: []*v1.PersistentVolumeClaim{}, - unboundClaimsDelayBinding: []*v1.PersistentVolumeClaim{}, - } - - for _, vol := range pod.Spec.Volumes { - volumeBound, pvc, err := b.isVolumeBound(logger, pod, &vol) - if err != nil { - return podVolumeClaims, err - } - if pvc == nil { - continue - } - if volumeBound { - podVolumeClaims.boundClaims = append(podVolumeClaims.boundClaims, pvc) - } else { - delayBindingMode, err := volume.IsDelayBindingMode(pvc, b.classLister) - if err != nil { - return podVolumeClaims, err - } - // Prebound PVCs are treated as unbound immediate binding - if delayBindingMode && pvc.Spec.VolumeName == "" { - // Scheduler path - podVolumeClaims.unboundClaimsDelayBinding = append(podVolumeClaims.unboundClaimsDelayBinding, pvc) - } else { - // !delayBindingMode || pvc.Spec.VolumeName != "" - // Immediate binding should have already been bound - podVolumeClaims.unboundClaimsImmediate = append(podVolumeClaims.unboundClaimsImmediate, pvc) - } - } - } - - podVolumeClaims.unboundVolumesDelayBinding = map[string][]*v1.PersistentVolume{} - for _, pvc := range podVolumeClaims.unboundClaimsDelayBinding { - // Get storage class name from each PVC - storageClassName := volume.GetPersistentVolumeClaimClass(pvc) - podVolumeClaims.unboundVolumesDelayBinding[storageClassName] = b.pvCache.ListPVs(storageClassName) - } - return podVolumeClaims, nil -} - -func (b *volumeBinder) checkBoundClaims(logger klog.Logger, claims []*v1.PersistentVolumeClaim, node *v1.Node, pod *v1.Pod) (bool, bool, error) { - csiNode, err := b.csiNodeLister.Get(node.Name) - if err != nil { - // TODO: return the error once CSINode is created by default - logger.V(4).Info("Could not get a CSINode object for the node", "node", klog.KObj(node), "err", err) - } - - for _, pvc := range claims { - pvName := pvc.Spec.VolumeName - pv, err := b.pvCache.GetPV(pvName) - if err != nil { - if errors.Is(err, assumecache.ErrNotFound) { - err = nil - } - return true, false, err - } - - pv, err = b.tryTranslatePVToCSI(logger, pv, csiNode) - if err != nil { - return false, true, err - } - - err = volume.CheckNodeAffinity(pv, node.Labels) - if err != nil { - logger.V(4).Info("PersistentVolume and node mismatch for pod", "PV", klog.KRef("", pvName), "node", klog.KObj(node), "pod", klog.KObj(pod), "err", err) - return false, true, nil - } - logger.V(5).Info("PersistentVolume and node matches for pod", "PV", klog.KRef("", pvName), "node", klog.KObj(node), "pod", klog.KObj(pod)) - } - - logger.V(4).Info("All bound volumes for pod match with node", "pod", klog.KObj(pod), "node", klog.KObj(node)) - return true, true, nil -} - -// findMatchingVolumes tries to find matching volumes for given claims, -// and return unbound claims for further provision. -func (b *volumeBinder) findMatchingVolumes(logger klog.Logger, pod *v1.Pod, claimsToBind []*v1.PersistentVolumeClaim, unboundVolumesDelayBinding map[string][]*v1.PersistentVolume, node *v1.Node) (foundMatches bool, bindings []*BindingInfo, unboundClaims []*v1.PersistentVolumeClaim, err error) { - // Sort all the claims by increasing size request to get the smallest fits - sort.Sort(byPVCSize(claimsToBind)) - - chosenPVs := map[string]*v1.PersistentVolume{} - - foundMatches = true - - for _, pvc := range claimsToBind { - // Get storage class name from each PVC - storageClassName := volume.GetPersistentVolumeClaimClass(pvc) - pvs := unboundVolumesDelayBinding[storageClassName] - - // Find a matching PV - pv, err := volume.FindMatchingVolume(pvc, pvs, node, chosenPVs, true, b.enableVolumeAttributesClass) - if err != nil { - return false, nil, nil, err - } - if pv == nil { - logger.V(4).Info("No matching volumes for pod", "pod", klog.KObj(pod), "PVC", klog.KObj(pvc), "node", klog.KObj(node)) - unboundClaims = append(unboundClaims, pvc) - foundMatches = false - continue - } - - // matching PV needs to be excluded so we don't select it again - chosenPVs[pv.Name] = pv - bindings = append(bindings, &BindingInfo{pv: pv, pvc: pvc}) - logger.V(5).Info("Found matching PV for PVC for pod", "PV", klog.KObj(pv), "PVC", klog.KObj(pvc), "node", klog.KObj(node), "pod", klog.KObj(pod)) - } - - if foundMatches { - logger.V(4).Info("Found matching volumes for pod", "pod", klog.KObj(pod), "node", klog.KObj(node)) - } - - return -} - -// checkVolumeProvisions checks given unbound claims (the claims have gone through func -// findMatchingVolumes, and do not have matching volumes for binding), and return true -// if all of the claims are eligible for dynamic provision. -func (b *volumeBinder) checkVolumeProvisions(logger klog.Logger, pod *v1.Pod, claimsToProvision []*v1.PersistentVolumeClaim, node *v1.Node) (provisionSatisfied, sufficientStorage bool, dynamicProvisions []*DynamicProvision, err error) { - dynamicProvisions = []*DynamicProvision{} - - // We return early with provisionedClaims == nil if a check - // fails or we encounter an error. - for _, claim := range claimsToProvision { - pvcName := getPVCName(claim) - className := volume.GetPersistentVolumeClaimClass(claim) - if className == "" { - return false, false, nil, fmt.Errorf("no class for claim %q", pvcName) - } - - class, err := b.classLister.Get(className) - if err != nil { - return false, false, nil, fmt.Errorf("failed to find storage class %q", className) - } - provisioner := class.Provisioner - if provisioner == "" || provisioner == volume.NotSupportedProvisioner { - logger.V(4).Info("Storage class of claim does not support dynamic provisioning", "storageClassName", className, "PVC", klog.KObj(claim)) - return false, true, nil, nil - } - - // Check if the node can satisfy the topology requirement in the class - if !v1helper.MatchTopologySelectorTerms(class.AllowedTopologies, labels.Set(node.Labels)) { - logger.V(4).Info("Node cannot satisfy provisioning topology requirements of claim", "node", klog.KObj(node), "PVC", klog.KObj(claim)) - return false, true, nil, nil - } - - // Check storage capacity. - sufficient, capacity, err := b.hasEnoughCapacity(logger, provisioner, claim, class, node) - if err != nil { - return false, false, nil, err - } - if !sufficient { - // hasEnoughCapacity logs an explanation. - return true, false, nil, nil - } - - dynamicProvisions = append(dynamicProvisions, &DynamicProvision{ - PVC: claim, - NodeCapacity: capacity, - }) - } - logger.V(4).Info("Provisioning for claims of pod that has no matching volumes...", "claimCount", len(claimsToProvision), "pod", klog.KObj(pod), "node", klog.KObj(node)) - - return true, true, dynamicProvisions, nil -} - -func (b *volumeBinder) revertAssumedPVs(bindings []*BindingInfo) { - for _, BindingInfo := range bindings { - b.pvCache.Restore(BindingInfo.pv.Name) - } -} - -func (b *volumeBinder) revertAssumedPVCs(claims []*v1.PersistentVolumeClaim) { - for _, claim := range claims { - b.pvcCache.Restore(getPVCName(claim)) - } -} - -// hasEnoughCapacity checks whether the provisioner has enough capacity left for a new volume of the given size -// that is available from the node. This function returns the node capacity based on the PVC's storage class. -func (b *volumeBinder) hasEnoughCapacity(logger klog.Logger, provisioner string, claim *v1.PersistentVolumeClaim, storageClass *storagev1.StorageClass, node *v1.Node) (bool, *storagev1.CSIStorageCapacity, error) { - quantity, ok := claim.Spec.Resources.Requests[v1.ResourceStorage] - if !ok { - // No capacity to check for. - return true, nil, nil - } - - // Only enabled for CSI drivers which opt into it. - driver, err := b.csiDriverLister.Get(provisioner) - if err != nil { - if apierrors.IsNotFound(err) { - // Either the provisioner is not a CSI driver or the driver does not - // opt into storage capacity scheduling. Either way, skip - // capacity checking. - return true, nil, nil - } - return false, nil, err - } - if driver.Spec.StorageCapacity == nil || !*driver.Spec.StorageCapacity { - return true, nil, nil - } - - // Look for a matching CSIStorageCapacity object(s). - // TODO (for beta): benchmark this and potentially introduce some kind of lookup structure (https://github.com/kubernetes/enhancements/issues/1698#issuecomment-654356718). - capacities, err := b.csiStorageCapacityLister.List(labels.Everything()) - if err != nil { - return false, nil, err - } - - sizeInBytes := quantity.Value() - for _, capacity := range capacities { - if capacity.StorageClassName == storageClass.Name && - capacitySufficient(capacity, sizeInBytes) && - b.nodeHasAccess(logger, node, capacity) { - // Enough capacity found. - return true, capacity, nil - } - } - - // TODO (?): this doesn't give any information about which pools where considered and why - // they had to be rejected. Log that above? But that might be a lot of log output... - logger.V(4).Info("Node has no accessible CSIStorageCapacity with enough capacity for PVC", - "node", klog.KObj(node), "PVC", klog.KObj(claim), "size", sizeInBytes, "storageClass", klog.KObj(storageClass)) - return false, nil, nil -} - -func capacitySufficient(capacity *storagev1.CSIStorageCapacity, sizeInBytes int64) bool { - limit := volumeLimit(capacity) - return limit != nil && limit.Value() >= sizeInBytes -} - -func volumeLimit(capacity *storagev1.CSIStorageCapacity) *resource.Quantity { - if capacity.MaximumVolumeSize != nil { - // Prefer MaximumVolumeSize if available, it is more precise. - return capacity.MaximumVolumeSize - } - return capacity.Capacity -} - -func (b *volumeBinder) nodeHasAccess(logger klog.Logger, node *v1.Node, capacity *storagev1.CSIStorageCapacity) bool { - if capacity.NodeTopology == nil { - // Unavailable - return false - } - // Only matching by label is supported. - selector, err := metav1.LabelSelectorAsSelector(capacity.NodeTopology) - if err != nil { - logger.Error(err, "Unexpected error converting to a label selector", "nodeTopology", capacity.NodeTopology) - return false - } - return selector.Matches(labels.Set(node.Labels)) -} - -type byPVCSize []*v1.PersistentVolumeClaim - -func (a byPVCSize) Len() int { - return len(a) -} - -func (a byPVCSize) Swap(i, j int) { - a[i], a[j] = a[j], a[i] -} - -func (a byPVCSize) Less(i, j int) bool { - iSize := a[i].Spec.Resources.Requests[v1.ResourceStorage] - jSize := a[j].Spec.Resources.Requests[v1.ResourceStorage] - // return true if iSize is less than jSize - return iSize.Cmp(jSize) == -1 -} - -// isCSIMigrationOnForPlugin checks if CSI migration is enabled for a given plugin. -func isCSIMigrationOnForPlugin(pluginName string, enableCSIMigrationPortworx bool) bool { - switch pluginName { - case csiplugins.AWSEBSInTreePluginName: - return true - case csiplugins.GCEPDInTreePluginName: - return true - case csiplugins.AzureDiskInTreePluginName: - return true - case csiplugins.CinderInTreePluginName: - return true - case csiplugins.PortworxVolumePluginName: - return enableCSIMigrationPortworx - } - return false -} - -// isPluginMigratedToCSIOnNode checks if an in-tree plugin has been migrated to a CSI driver on the node. -func isPluginMigratedToCSIOnNode(pluginName string, csiNode *storagev1.CSINode) bool { - if csiNode == nil { - return false - } - - csiNodeAnn := csiNode.GetAnnotations() - if csiNodeAnn == nil { - return false - } - - var mpaSet sets.Set[string] - mpa := csiNodeAnn[v1.MigratedPluginsAnnotationKey] - if len(mpa) == 0 { - mpaSet = sets.New[string]() - } else { - tok := strings.Split(mpa, ",") - mpaSet = sets.New(tok...) - } - - return mpaSet.Has(pluginName) -} - -// tryTranslatePVToCSI will translate the in-tree PV to CSI if it meets the criteria. If not, it returns the unmodified in-tree PV. -func (b *volumeBinder) tryTranslatePVToCSI(logger klog.Logger, pv *v1.PersistentVolume, csiNode *storagev1.CSINode) (*v1.PersistentVolume, error) { - if !b.translator.IsPVMigratable(pv) { - return pv, nil - } - - pluginName, err := b.translator.GetInTreePluginNameFromSpec(pv, nil) - if err != nil { - return nil, fmt.Errorf("could not get plugin name from pv: %v", err) - } - - if !isCSIMigrationOnForPlugin(pluginName, b.enableCSIMigrationPortworx) { - return pv, nil - } - - if !isPluginMigratedToCSIOnNode(pluginName, csiNode) { - return pv, nil - } - - transPV, err := b.translator.TranslateInTreePVToCSI(logger, pv) - if err != nil { - return nil, fmt.Errorf("could not translate pv: %v", err) - } - - return transPV, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/fake_binder.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/fake_binder.go deleted file mode 100644 index f563c3c75..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/fake_binder.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumebinding - -import ( - "context" - - v1 "k8s.io/api/core/v1" - "k8s.io/klog/v2" -) - -// FakeVolumeBinderConfig holds configurations for fake volume binder. -type FakeVolumeBinderConfig struct { - AllBound bool - FindReasons ConflictReasons - FindErr error - AssumeErr error - BindErr error -} - -// NewFakeVolumeBinder sets up all the caches needed for the scheduler to make -// topology-aware volume binding decisions. -func NewFakeVolumeBinder(config *FakeVolumeBinderConfig) *FakeVolumeBinder { - return &FakeVolumeBinder{ - config: config, - } -} - -// FakeVolumeBinder represents a fake volume binder for testing. -type FakeVolumeBinder struct { - config *FakeVolumeBinderConfig - AssumeCalled bool - BindCalled bool -} - -var _ SchedulerVolumeBinder = &FakeVolumeBinder{} - -// GetPodVolumeClaims implements SchedulerVolumeBinder.GetPodVolumes. -func (b *FakeVolumeBinder) GetPodVolumeClaims(_ klog.Logger, pod *v1.Pod) (podVolumeClaims *PodVolumeClaims, err error) { - return &PodVolumeClaims{}, nil -} - -// FindPodVolumes implements SchedulerVolumeBinder.FindPodVolumes. -func (b *FakeVolumeBinder) FindPodVolumes(_ klog.Logger, pod *v1.Pod, _ *PodVolumeClaims, node *v1.Node) (podVolumes *PodVolumes, reasons ConflictReasons, err error) { - return nil, b.config.FindReasons, b.config.FindErr -} - -// AssumePodVolumes implements SchedulerVolumeBinder.AssumePodVolumes. -func (b *FakeVolumeBinder) AssumePodVolumes(_ klog.Logger, assumedPod *v1.Pod, nodeName string, podVolumes *PodVolumes) (bool, error) { - b.AssumeCalled = true - return b.config.AllBound, b.config.AssumeErr -} - -// RevertAssumedPodVolumes implements SchedulerVolumeBinder.RevertAssumedPodVolumes -func (b *FakeVolumeBinder) RevertAssumedPodVolumes(_ *PodVolumes) {} - -// BindPodVolumes implements SchedulerVolumeBinder.BindPodVolumes. -func (b *FakeVolumeBinder) BindPodVolumes(ctx context.Context, assumedPod *v1.Pod, podVolumes *PodVolumes) error { - b.BindCalled = true - return b.config.BindErr -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics/metrics.go deleted file mode 100644 index a52b19632..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics/metrics.go +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package metrics - -import ( - "k8s.io/component-base/metrics" - "k8s.io/component-base/metrics/legacyregistry" -) - -// VolumeSchedulerSubsystem - subsystem name used by scheduler -const VolumeSchedulerSubsystem = "scheduler_volume" - -var ( - // VolumeBindingRequestSchedulerBinderCache tracks the number of volume binder cache operations. - VolumeBindingRequestSchedulerBinderCache = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: VolumeSchedulerSubsystem, - Name: "binder_cache_requests_total", - Help: "Total number for request volume binding cache", - StabilityLevel: metrics.ALPHA, - }, - []string{"operation"}, - ) - // VolumeSchedulingStageFailed tracks the number of failed volume scheduling operations. - VolumeSchedulingStageFailed = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: VolumeSchedulerSubsystem, - Name: "scheduling_stage_error_total", - Help: "Volume scheduling stage error count", - StabilityLevel: metrics.ALPHA, - }, - []string{"operation"}, - ) -) - -// RegisterVolumeSchedulingMetrics is used for scheduler, because the volume binding cache is a library -// used by scheduler process. -func RegisterVolumeSchedulingMetrics() { - legacyregistry.MustRegister(VolumeBindingRequestSchedulerBinderCache) - legacyregistry.MustRegister(VolumeSchedulingStageFailed) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/scorer.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/scorer.go deleted file mode 100644 index 4c079f28d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/scorer.go +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumebinding - -import ( - "math" - - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" -) - -// classResourceMap holds a map of storage class to resource. -type classResourceMap map[string]*StorageResource - -// volumeCapacityScorer calculates the score based on class storage resource information. -type volumeCapacityScorer func(classResourceMap) int64 - -// buildScorerFunction builds volumeCapacityScorer from the scoring function shape. -func buildScorerFunction(scoringFunctionShape helper.FunctionShape) volumeCapacityScorer { - rawScoringFunction := helper.BuildBrokenLinearFunction(scoringFunctionShape) - f := func(requested, capacity int64) int64 { - if capacity == 0 || requested > capacity { - return rawScoringFunction(maxUtilization) - } - - return rawScoringFunction(requested * maxUtilization / capacity) - } - return func(classResources classResourceMap) int64 { - var nodeScore int64 - // in alpha stage, all classes have the same weight - weightSum := len(classResources) - if weightSum == 0 { - return 0 - } - for _, resource := range classResources { - classScore := f(resource.Requested, resource.Capacity) - nodeScore += classScore - } - return int64(math.Round(float64(nodeScore) / float64(weightSum))) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/test_utils.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/test_utils.go deleted file mode 100644 index 23675f969..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/test_utils.go +++ /dev/null @@ -1,217 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumebinding - -import ( - "fmt" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/component-helpers/storage/volume" - "k8s.io/utils/ptr" -) - -type nodeBuilder struct { - *v1.Node -} - -func makeNode(name string) nodeBuilder { - return nodeBuilder{Node: &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - v1.LabelHostname: name, - }, - }, - }} -} - -func (nb nodeBuilder) withLabel(key, value string) nodeBuilder { - if nb.Node.ObjectMeta.Labels == nil { - nb.Node.ObjectMeta.Labels = map[string]string{} - } - nb.Node.ObjectMeta.Labels[key] = value - return nb -} - -type pvBuilder struct { - *v1.PersistentVolume -} - -func makePV(name, className string) pvBuilder { - return pvBuilder{PersistentVolume: &v1.PersistentVolume{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Spec: v1.PersistentVolumeSpec{ - StorageClassName: className, - }, - }} -} - -func (pvb pvBuilder) withNodeAffinity(keyValues map[string][]string) pvBuilder { - matchExpressions := make([]v1.NodeSelectorRequirement, 0) - for key, values := range keyValues { - matchExpressions = append(matchExpressions, v1.NodeSelectorRequirement{ - Key: key, - Operator: v1.NodeSelectorOpIn, - Values: values, - }) - } - pvb.PersistentVolume.Spec.NodeAffinity = &v1.VolumeNodeAffinity{ - Required: &v1.NodeSelector{ - NodeSelectorTerms: []v1.NodeSelectorTerm{ - { - MatchExpressions: matchExpressions, - }, - }, - }, - } - return pvb -} - -func (pvb pvBuilder) withVersion(version string) pvBuilder { - pvb.PersistentVolume.ObjectMeta.ResourceVersion = version - return pvb -} - -func (pvb pvBuilder) withCapacity(capacity resource.Quantity) pvBuilder { - pvb.PersistentVolume.Spec.Capacity = v1.ResourceList{ - v1.ResourceName(v1.ResourceStorage): capacity, - } - return pvb -} - -func (pvb pvBuilder) withPhase(phase v1.PersistentVolumePhase) pvBuilder { - pvb.PersistentVolume.Status = v1.PersistentVolumeStatus{ - Phase: phase, - } - return pvb -} - -type pvcBuilder struct { - *v1.PersistentVolumeClaim -} - -func makePVC(name string, storageClassName string) pvcBuilder { - return pvcBuilder{PersistentVolumeClaim: &v1.PersistentVolumeClaim{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: v1.NamespaceDefault, - }, - Spec: v1.PersistentVolumeClaimSpec{ - StorageClassName: ptr.To(storageClassName), - }, - }} -} - -func (pvcb pvcBuilder) withBoundPV(pvName string) pvcBuilder { - pvcb.PersistentVolumeClaim.Spec.VolumeName = pvName - metav1.SetMetaDataAnnotation(&pvcb.PersistentVolumeClaim.ObjectMeta, volume.AnnBindCompleted, "true") - return pvcb -} - -func (pvcb pvcBuilder) withRequestStorage(request resource.Quantity) pvcBuilder { - pvcb.PersistentVolumeClaim.Spec.Resources = v1.VolumeResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceName(v1.ResourceStorage): request, - }, - } - return pvcb -} - -func (pvcb pvcBuilder) withPhase(phase v1.PersistentVolumeClaimPhase) pvcBuilder { - pvcb.PersistentVolumeClaim.Status = v1.PersistentVolumeClaimStatus{ - Phase: phase, - } - return pvcb -} - -type podBuilder struct { - *v1.Pod -} - -func makePod(name string) podBuilder { - pb := podBuilder{Pod: &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: v1.NamespaceDefault, - }, - }} - pb.Pod.Spec.Volumes = make([]v1.Volume, 0) - return pb -} - -func (pb podBuilder) withNodeName(name string) podBuilder { - pb.Pod.Spec.NodeName = name - return pb -} - -func (pb podBuilder) withNamespace(name string) podBuilder { - pb.Pod.ObjectMeta.Namespace = name - return pb -} - -func (pb podBuilder) withPVCVolume(pvcName, name string) podBuilder { - pb.Pod.Spec.Volumes = append(pb.Pod.Spec.Volumes, v1.Volume{ - Name: name, - VolumeSource: v1.VolumeSource{ - PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ - ClaimName: pvcName, - }, - }, - }) - return pb -} - -func (pb podBuilder) withPVCSVolume(pvcs []*v1.PersistentVolumeClaim) podBuilder { - for i, pvc := range pvcs { - pb.withPVCVolume(pvc.Name, fmt.Sprintf("vol%v", i)) - } - return pb -} - -func (pb podBuilder) withEmptyDirVolume() podBuilder { - pb.Pod.Spec.Volumes = append(pb.Pod.Spec.Volumes, v1.Volume{ - VolumeSource: v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{}, - }, - }) - return pb -} - -func (pb podBuilder) withGenericEphemeralVolume(name string) podBuilder { - pb.Pod.Spec.Volumes = append(pb.Pod.Spec.Volumes, v1.Volume{ - Name: name, - VolumeSource: v1.VolumeSource{ - Ephemeral: &v1.EphemeralVolumeSource{}, - }, - }) - return pb -} - -func (pb podBuilder) withCSI(driver string) podBuilder { - pb.Pod.Spec.Volumes = append(pb.Pod.Spec.Volumes, v1.Volume{ - VolumeSource: v1.VolumeSource{ - CSI: &v1.CSIVolumeSource{ - Driver: driver, - }, - }, - }) - return pb -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go deleted file mode 100644 index 16179ec6b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/volume_binding.go +++ /dev/null @@ -1,630 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumebinding - -import ( - "context" - "errors" - "fmt" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - storagev1 "k8s.io/api/storage/v1" - apiequality "k8s.io/apimachinery/pkg/api/equality" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - corelisters "k8s.io/client-go/listers/core/v1" - storagelisters "k8s.io/client-go/listers/storage/v1" - "k8s.io/component-helpers/storage/ephemeral" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -const ( - stateKey framework.StateKey = Name - - maxUtilization = 100 -) - -// the state is initialized in PreFilter phase. because we save the pointer in -// framework.CycleState, in the later phases we don't need to call Write method -// to update the value -type stateData struct { - allBound bool - // podVolumesByNode holds the pod's volume information found in the Filter - // phase for each node - // it's initialized in the PreFilter phase - podVolumesByNode map[string]*PodVolumes - podVolumeClaims *PodVolumeClaims - // hasStaticBindings declares whether the pod contains one or more StaticBinding. - // If not, vloumeBinding will skip score extension point. - hasStaticBindings bool - sync.Mutex -} - -func (d *stateData) Clone() framework.StateData { - return d -} - -// VolumeBinding is a plugin that binds pod volumes in scheduling. -// In the Filter phase, pod binding cache is created for the pod and used in -// Reserve and PreBind phases. -type VolumeBinding struct { - Binder SchedulerVolumeBinder - PVCLister corelisters.PersistentVolumeClaimLister - classLister storagelisters.StorageClassLister - scorer volumeCapacityScorer - fts feature.Features -} - -var _ framework.PreFilterPlugin = &VolumeBinding{} -var _ framework.FilterPlugin = &VolumeBinding{} -var _ framework.ReservePlugin = &VolumeBinding{} -var _ framework.PreBindPlugin = &VolumeBinding{} -var _ framework.PreScorePlugin = &VolumeBinding{} -var _ framework.ScorePlugin = &VolumeBinding{} -var _ framework.EnqueueExtensions = &VolumeBinding{} - -// Name is the name of the plugin used in Registry and configurations. -const Name = names.VolumeBinding - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *VolumeBinding) Name() string { - return Name -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *VolumeBinding) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // Pods may fail to find available PVs because the node labels do not - // match the storage class's allowed topologies or PV's node affinity. - // A new or updated node may make pods schedulable. - // - // A note about UpdateNodeTaint event: - // Ideally, it's supposed to register only Add | UpdateNodeLabel because UpdateNodeTaint will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeLabel | framework.UpdateNodeTaint - if pl.fts.EnableSchedulingQueueHint { - // When scheduling queue hint is enabled, we don't use the problematic preCheck and don't need to register UpdateNodeTaint event. - nodeActionType = framework.Add | framework.UpdateNodeLabel - } - events := []framework.ClusterEventWithHint{ - // Pods may fail because of missing or mis-configured storage class - // (e.g., allowedTopologies, volumeBindingMode), and hence may become - // schedulable upon StorageClass Add or Update events. - {Event: framework.ClusterEvent{Resource: framework.StorageClass, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterStorageClassChange}, - - // We bind PVCs with PVs, so any changes may make the pods schedulable. - {Event: framework.ClusterEvent{Resource: framework.PersistentVolumeClaim, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterPersistentVolumeClaimChange}, - {Event: framework.ClusterEvent{Resource: framework.PersistentVolume, ActionType: framework.Add | framework.Update}}, - - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}}, - - // We rely on CSI node to translate in-tree PV to CSI. - // TODO: kube-schduler will unregister the CSINode events once all the volume plugins has completed their CSI migration. - {Event: framework.ClusterEvent{Resource: framework.CSINode, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterCSINodeChange}, - - // When CSIStorageCapacity is enabled, pods may become schedulable - // on CSI driver & storage capacity changes. - {Event: framework.ClusterEvent{Resource: framework.CSIDriver, ActionType: framework.Update}, QueueingHintFn: pl.isSchedulableAfterCSIDriverChange}, - {Event: framework.ClusterEvent{Resource: framework.CSIStorageCapacity, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterCSIStorageCapacityChange}, - } - return events, nil -} - -func (pl *VolumeBinding) isSchedulableAfterCSINodeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - if oldObj == nil { - logger.V(5).Info("CSINode creation could make the pod schedulable") - return framework.Queue, nil - } - oldCSINode, modifiedCSINode, err := util.As[*storagev1.CSINode](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - logger = klog.LoggerWithValues( - logger, - "Pod", klog.KObj(pod), - "CSINode", klog.KObj(modifiedCSINode), - ) - - if oldCSINode.ObjectMeta.Annotations[v1.MigratedPluginsAnnotationKey] != modifiedCSINode.ObjectMeta.Annotations[v1.MigratedPluginsAnnotationKey] { - logger.V(5).Info("CSINode's migrated plugins annotation is updated and that may make the pod schedulable") - return framework.Queue, nil - } - - logger.V(5).Info("CISNode was created or updated but it doesn't make this pod schedulable") - return framework.QueueSkip, nil -} - -func (pl *VolumeBinding) isSchedulableAfterPersistentVolumeClaimChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, newPVC, err := util.As[*v1.PersistentVolumeClaim](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - logger = klog.LoggerWithValues( - logger, - "Pod", klog.KObj(pod), - "PersistentVolumeClaim", klog.KObj(newPVC), - ) - - if pod.Namespace != newPVC.Namespace { - logger.V(5).Info("PersistentVolumeClaim was created or updated, but it doesn't make this pod schedulable because the PVC belongs to a different namespace") - return framework.QueueSkip, nil - } - - for _, vol := range pod.Spec.Volumes { - var pvcName string - switch { - case vol.PersistentVolumeClaim != nil: - pvcName = vol.PersistentVolumeClaim.ClaimName - case vol.Ephemeral != nil: - pvcName = ephemeral.VolumeClaimName(pod, &vol) - default: - continue - } - - if pvcName == newPVC.Name { - // Return Queue because, in this case, - // all PVC creations and almost all PVC updates could make the Pod schedulable. - logger.V(5).Info("PersistentVolumeClaim the pod requires was created or updated, potentially making the target Pod schedulable") - return framework.Queue, nil - } - } - - logger.V(5).Info("PersistentVolumeClaim was created or updated, but it doesn't make this pod schedulable") - return framework.QueueSkip, nil -} - -// isSchedulableAfterStorageClassChange checks whether an StorageClass event might make a Pod schedulable or not. -// Any StorageClass addition and a StorageClass update to allowedTopologies -// might make a Pod schedulable. -// Note that an update to volume binding mode is not allowed and we don't have to consider while examining the update event. -func (pl *VolumeBinding) isSchedulableAfterStorageClassChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - oldSC, newSC, err := util.As[*storagev1.StorageClass](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - logger = klog.LoggerWithValues( - logger, - "Pod", klog.KObj(pod), - "StorageClass", klog.KObj(newSC), - ) - - if oldSC == nil { - // No further filtering can be made for a creation event, - // and we just always return Queue. - logger.V(5).Info("A new StorageClass was created, which could make a Pod schedulable") - return framework.Queue, nil - } - - if !apiequality.Semantic.DeepEqual(newSC.AllowedTopologies, oldSC.AllowedTopologies) { - logger.V(5).Info("StorageClass got an update in AllowedTopologies", "AllowedTopologies", newSC.AllowedTopologies) - return framework.Queue, nil - } - - logger.V(5).Info("StorageClass was updated, but it doesn't make this pod schedulable") - return framework.QueueSkip, nil -} - -// isSchedulableAfterCSIStorageCapacityChange checks whether a CSIStorageCapacity event -// might make a Pod schedulable or not. -// Any CSIStorageCapacity addition and a CSIStorageCapacity update to volume limit -// (calculated based on capacity and maximumVolumeSize) might make a Pod schedulable. -// Note that an update to nodeTopology and storageClassName is not allowed and -// we don't have to consider while examining the update event. -func (pl *VolumeBinding) isSchedulableAfterCSIStorageCapacityChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - oldCap, newCap, err := util.As[*storagev1.CSIStorageCapacity](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - if oldCap == nil { - logger.V(5).Info( - "A new CSIStorageCapacity was created, which could make a Pod schedulable", - "Pod", klog.KObj(pod), - "CSIStorageCapacity", klog.KObj(newCap), - ) - return framework.Queue, nil - } - - oldLimit := volumeLimit(oldCap) - newLimit := volumeLimit(newCap) - - logger = klog.LoggerWithValues( - logger, - "Pod", klog.KObj(pod), - "CSIStorageCapacity", klog.KObj(newCap), - "volumeLimit(new)", newLimit, - "volumeLimit(old)", oldLimit, - ) - - if newLimit != nil && (oldLimit == nil || newLimit.Value() > oldLimit.Value()) { - logger.V(5).Info("VolumeLimit was increased, which could make a Pod schedulable") - return framework.Queue, nil - } - - logger.V(5).Info("CSIStorageCapacity was updated, but it doesn't make this pod schedulable") - return framework.QueueSkip, nil -} - -func (pl *VolumeBinding) isSchedulableAfterCSIDriverChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalCSIDriver, modifiedCSIDriver, err := util.As[*storagev1.CSIDriver](oldObj, newObj) - if err != nil { - return framework.Queue, err - } - - logger = klog.LoggerWithValues( - logger, - "Pod", klog.KObj(pod), - "CSIDriver", klog.KObj(modifiedCSIDriver), - ) - - for _, vol := range pod.Spec.Volumes { - if vol.CSI == nil || vol.CSI.Driver != modifiedCSIDriver.Name { - continue - } - if (originalCSIDriver.Spec.StorageCapacity != nil && *originalCSIDriver.Spec.StorageCapacity) && - (modifiedCSIDriver.Spec.StorageCapacity == nil || !*modifiedCSIDriver.Spec.StorageCapacity) { - logger.V(5).Info("CSIDriver was updated and storage capacity got disabled, which may make the pod schedulable") - return framework.Queue, nil - } - } - - logger.V(5).Info("CSIDriver was created or updated but it doesn't make this pod schedulable") - return framework.QueueSkip, nil -} - -// podHasPVCs returns 2 values: -// - the first one to denote if the given "pod" has any PVC defined. -// - the second one to return any error if the requested PVC is illegal. -func (pl *VolumeBinding) podHasPVCs(pod *v1.Pod) (bool, error) { - hasPVC := false - for _, vol := range pod.Spec.Volumes { - var pvcName string - isEphemeral := false - switch { - case vol.PersistentVolumeClaim != nil: - pvcName = vol.PersistentVolumeClaim.ClaimName - case vol.Ephemeral != nil: - pvcName = ephemeral.VolumeClaimName(pod, &vol) - isEphemeral = true - default: - // Volume is not using a PVC, ignore - continue - } - hasPVC = true - pvc, err := pl.PVCLister.PersistentVolumeClaims(pod.Namespace).Get(pvcName) - if err != nil { - // The error usually has already enough context ("persistentvolumeclaim "myclaim" not found"), - // but we can do better for generic ephemeral inline volumes where that situation - // is normal directly after creating a pod. - if isEphemeral && apierrors.IsNotFound(err) { - err = fmt.Errorf("waiting for ephemeral volume controller to create the persistentvolumeclaim %q", pvcName) - } - return hasPVC, err - } - - if pvc.Status.Phase == v1.ClaimLost { - return hasPVC, fmt.Errorf("persistentvolumeclaim %q bound to non-existent persistentvolume %q", pvc.Name, pvc.Spec.VolumeName) - } - - if pvc.DeletionTimestamp != nil { - return hasPVC, fmt.Errorf("persistentvolumeclaim %q is being deleted", pvc.Name) - } - - if isEphemeral { - if err := ephemeral.VolumeIsForPod(pod, pvc); err != nil { - return hasPVC, err - } - } - } - return hasPVC, nil -} - -// PreFilter invoked at the prefilter extension point to check if pod has all -// immediate PVCs bound. If not all immediate PVCs are bound, an -// UnschedulableAndUnresolvable is returned. -func (pl *VolumeBinding) PreFilter(ctx context.Context, state *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - logger := klog.FromContext(ctx) - // If pod does not reference any PVC, we don't need to do anything. - if hasPVC, err := pl.podHasPVCs(pod); err != nil { - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, err.Error()) - } else if !hasPVC { - state.Write(stateKey, &stateData{}) - return nil, framework.NewStatus(framework.Skip) - } - podVolumeClaims, err := pl.Binder.GetPodVolumeClaims(logger, pod) - if err != nil { - return nil, framework.AsStatus(err) - } - if len(podVolumeClaims.unboundClaimsImmediate) > 0 { - // Return UnschedulableAndUnresolvable error if immediate claims are - // not bound. Pod will be moved to active/backoff queues once these - // claims are bound by PV controller. - status := framework.NewStatus(framework.UnschedulableAndUnresolvable) - status.AppendReason("pod has unbound immediate PersistentVolumeClaims") - return nil, status - } - state.Write(stateKey, &stateData{ - podVolumesByNode: make(map[string]*PodVolumes), - podVolumeClaims: &PodVolumeClaims{ - boundClaims: podVolumeClaims.boundClaims, - unboundClaimsDelayBinding: podVolumeClaims.unboundClaimsDelayBinding, - unboundVolumesDelayBinding: podVolumeClaims.unboundVolumesDelayBinding, - }, - }) - return nil, nil -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (pl *VolumeBinding) PreFilterExtensions() framework.PreFilterExtensions { - return nil -} - -func getStateData(cs *framework.CycleState) (*stateData, error) { - state, err := cs.Read(stateKey) - if err != nil { - return nil, err - } - s, ok := state.(*stateData) - if !ok { - return nil, errors.New("unable to convert state into stateData") - } - return s, nil -} - -// Filter invoked at the filter extension point. -// It evaluates if a pod can fit due to the volumes it requests, -// for both bound and unbound PVCs. -// -// For PVCs that are bound, then it checks that the corresponding PV's node affinity is -// satisfied by the given node. -// -// For PVCs that are unbound, it tries to find available PVs that can satisfy the PVC requirements -// and that the PV node affinity is satisfied by the given node. -// -// If storage capacity tracking is enabled, then enough space has to be available -// for the node and volumes that still need to be created. -// -// The predicate returns true if all bound PVCs have compatible PVs with the node, and if all unbound -// PVCs can be matched with an available and node-compatible PV. -func (pl *VolumeBinding) Filter(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - logger := klog.FromContext(ctx) - node := nodeInfo.Node() - - state, err := getStateData(cs) - if err != nil { - return framework.AsStatus(err) - } - - podVolumes, reasons, err := pl.Binder.FindPodVolumes(logger, pod, state.podVolumeClaims, node) - - if err != nil { - return framework.AsStatus(err) - } - - if len(reasons) > 0 { - status := framework.NewStatus(framework.UnschedulableAndUnresolvable) - for _, reason := range reasons { - status.AppendReason(string(reason)) - } - return status - } - - // multiple goroutines call `Filter` on different nodes simultaneously and the `CycleState` may be duplicated, so we must use a local lock here - state.Lock() - state.podVolumesByNode[node.Name] = podVolumes - state.hasStaticBindings = state.hasStaticBindings || (podVolumes != nil && len(podVolumes.StaticBindings) > 0) - state.Unlock() - return nil -} - -// PreScore invoked at the preScore extension point. It checks whether volumeBinding can skip Score -func (pl *VolumeBinding) PreScore(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) *framework.Status { - if pl.scorer == nil { - return framework.NewStatus(framework.Skip) - } - state, err := getStateData(cs) - if err != nil { - return framework.AsStatus(err) - } - if state.hasStaticBindings || pl.fts.EnableStorageCapacityScoring { - return nil - } - return framework.NewStatus(framework.Skip) -} - -// Score invoked at the score extension point. -func (pl *VolumeBinding) Score(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - if pl.scorer == nil { - return 0, nil - } - state, err := getStateData(cs) - if err != nil { - return 0, framework.AsStatus(err) - } - nodeName := nodeInfo.Node().Name - podVolumes, ok := state.podVolumesByNode[nodeName] - if !ok { - return 0, nil - } - - classResources := make(classResourceMap) - if len(podVolumes.StaticBindings) != 0 || !pl.fts.EnableStorageCapacityScoring { - // group static binding volumes by storage class - for _, staticBinding := range podVolumes.StaticBindings { - class := staticBinding.StorageClassName() - storageResource := staticBinding.StorageResource() - if _, ok := classResources[class]; !ok { - classResources[class] = &StorageResource{ - Requested: 0, - Capacity: 0, - } - } - classResources[class].Requested += storageResource.Requested - classResources[class].Capacity += storageResource.Capacity - } - } else { - // group dynamic binding volumes by storage class - for _, provision := range podVolumes.DynamicProvisions { - if provision.NodeCapacity == nil { - continue - } - class := *provision.PVC.Spec.StorageClassName - if _, ok := classResources[class]; !ok { - classResources[class] = &StorageResource{ - Requested: 0, - Capacity: 0, - } - } - // The following line cannot be +=. For example, if a Pod requests two 50GB volumes from - // a StorageClass with 100GB of capacity on a node, this part of the code will be executed twice. - // In that case, using += would incorrectly set classResources[class].Capacity to 200GB. - classResources[class].Capacity = provision.NodeCapacity.Capacity.Value() - requestedQty := provision.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)] - classResources[class].Requested += requestedQty.Value() - } - } - - return pl.scorer(classResources), nil -} - -// ScoreExtensions of the Score plugin. -func (pl *VolumeBinding) ScoreExtensions() framework.ScoreExtensions { - return nil -} - -// Reserve reserves volumes of pod and saves binding status in cycle state. -func (pl *VolumeBinding) Reserve(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { - state, err := getStateData(cs) - if err != nil { - return framework.AsStatus(err) - } - // we don't need to hold the lock as only one node will be reserved for the given pod - podVolumes, ok := state.podVolumesByNode[nodeName] - if ok { - allBound, err := pl.Binder.AssumePodVolumes(klog.FromContext(ctx), pod, nodeName, podVolumes) - if err != nil { - return framework.AsStatus(err) - } - state.allBound = allBound - } else { - // may not exist if the pod does not reference any PVC - state.allBound = true - } - return nil -} - -// PreBind will make the API update with the assumed bindings and wait until -// the PV controller has completely finished the binding operation. -// -// If binding errors, times out or gets undone, then an error will be returned to -// retry scheduling. -func (pl *VolumeBinding) PreBind(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { - s, err := getStateData(cs) - if err != nil { - return framework.AsStatus(err) - } - if s.allBound { - // no need to bind volumes - return nil - } - // we don't need to hold the lock as only one node will be pre-bound for the given pod - podVolumes, ok := s.podVolumesByNode[nodeName] - if !ok { - return framework.AsStatus(fmt.Errorf("no pod volumes found for node %q", nodeName)) - } - logger := klog.FromContext(ctx) - logger.V(5).Info("Trying to bind volumes for pod", "pod", klog.KObj(pod)) - err = pl.Binder.BindPodVolumes(ctx, pod, podVolumes) - if err != nil { - logger.V(5).Info("Failed to bind volumes for pod", "pod", klog.KObj(pod), "err", err) - return framework.AsStatus(err) - } - logger.V(5).Info("Success binding volumes for pod", "pod", klog.KObj(pod)) - return nil -} - -// Unreserve clears assumed PV and PVC cache. -// It's idempotent, and does nothing if no cache found for the given pod. -func (pl *VolumeBinding) Unreserve(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeName string) { - s, err := getStateData(cs) - if err != nil { - return - } - // we don't need to hold the lock as only one node may be unreserved - podVolumes, ok := s.podVolumesByNode[nodeName] - if !ok { - return - } - pl.Binder.RevertAssumedPodVolumes(podVolumes) -} - -// New initializes a new plugin and returns it. -func New(ctx context.Context, plArgs runtime.Object, fh framework.Handle, fts feature.Features) (framework.Plugin, error) { - args, ok := plArgs.(*config.VolumeBindingArgs) - if !ok { - return nil, fmt.Errorf("want args to be of type VolumeBindingArgs, got %T", plArgs) - } - if err := validation.ValidateVolumeBindingArgsWithOptions(nil, args, validation.VolumeBindingArgsValidationOptions{ - AllowStorageCapacityScoring: fts.EnableStorageCapacityScoring, - }); err != nil { - return nil, err - } - podInformer := fh.SharedInformerFactory().Core().V1().Pods() - nodeInformer := fh.SharedInformerFactory().Core().V1().Nodes() - pvcInformer := fh.SharedInformerFactory().Core().V1().PersistentVolumeClaims() - pvInformer := fh.SharedInformerFactory().Core().V1().PersistentVolumes() - storageClassInformer := fh.SharedInformerFactory().Storage().V1().StorageClasses() - csiNodeInformer := fh.SharedInformerFactory().Storage().V1().CSINodes() - capacityCheck := CapacityCheck{ - CSIDriverInformer: fh.SharedInformerFactory().Storage().V1().CSIDrivers(), - CSIStorageCapacityInformer: fh.SharedInformerFactory().Storage().V1().CSIStorageCapacities(), - } - binder := NewVolumeBinder(klog.FromContext(ctx), fh.ClientSet(), fts, podInformer, nodeInformer, csiNodeInformer, pvcInformer, pvInformer, storageClassInformer, capacityCheck, time.Duration(args.BindTimeoutSeconds)*time.Second) - - // build score function - var scorer volumeCapacityScorer - if fts.EnableStorageCapacityScoring { - shape := make(helper.FunctionShape, 0, len(args.Shape)) - for _, point := range args.Shape { - shape = append(shape, helper.FunctionShapePoint{ - Utilization: int64(point.Utilization), - Score: int64(point.Score) * (framework.MaxNodeScore / config.MaxCustomPriorityScore), - }) - } - scorer = buildScorerFunction(shape) - } - return &VolumeBinding{ - Binder: binder, - PVCLister: pvcInformer.Lister(), - classLister: storageClassInformer.Lister(), - scorer: scorer, - fts: fts, - }, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/OWNERS b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/OWNERS deleted file mode 100644 index be3245e85..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - sig-storage-approvers - - cofyc -reviewers: - - sig-storage-reviewers - - cofyc -labels: - - sig/storage diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go deleted file mode 100644 index 6b22340b4..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions/volume_restrictions.go +++ /dev/null @@ -1,426 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumerestrictions - -import ( - "context" - "fmt" - - v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/sets" - corelisters "k8s.io/client-go/listers/core/v1" - "k8s.io/klog/v2" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// VolumeRestrictions is a plugin that checks volume restrictions. -type VolumeRestrictions struct { - pvcLister corelisters.PersistentVolumeClaimLister - sharedLister framework.SharedLister - enableSchedulingQueueHint bool -} - -var _ framework.PreFilterPlugin = &VolumeRestrictions{} -var _ framework.FilterPlugin = &VolumeRestrictions{} -var _ framework.EnqueueExtensions = &VolumeRestrictions{} -var _ framework.StateData = &preFilterState{} - -const ( - // Name is the name of the plugin used in the plugin registry and configurations. - Name = names.VolumeRestrictions - // preFilterStateKey is the key in CycleState to VolumeRestrictions pre-computed data for Filtering. - // Using the name of the plugin will likely help us avoid collisions with other plugins. - preFilterStateKey = "PreFilter" + Name - - // ErrReasonDiskConflict is used for NoDiskConflict predicate error. - ErrReasonDiskConflict = "node(s) had no available disk" - // ErrReasonReadWriteOncePodConflict is used when a pod is found using the same PVC with the ReadWriteOncePod access mode. - ErrReasonReadWriteOncePodConflict = "node has pod using PersistentVolumeClaim with the same name and ReadWriteOncePod access mode" -) - -// preFilterState computed at PreFilter and used at Filter. -type preFilterState struct { - // Names of the pod's volumes using the ReadWriteOncePod access mode. - readWriteOncePodPVCs sets.Set[string] - // The number of references to these ReadWriteOncePod volumes by scheduled pods. - conflictingPVCRefCount int -} - -func (s *preFilterState) updateWithPod(podInfo *framework.PodInfo, multiplier int) { - s.conflictingPVCRefCount += multiplier * s.conflictingPVCRefCountForPod(podInfo) -} - -func (s *preFilterState) conflictingPVCRefCountForPod(podInfo *framework.PodInfo) int { - conflicts := 0 - for _, volume := range podInfo.Pod.Spec.Volumes { - if volume.PersistentVolumeClaim == nil { - continue - } - if s.readWriteOncePodPVCs.Has(volume.PersistentVolumeClaim.ClaimName) { - conflicts += 1 - } - } - return conflicts -} - -// Clone the prefilter state. -func (s *preFilterState) Clone() framework.StateData { - if s == nil { - return nil - } - return &preFilterState{ - readWriteOncePodPVCs: s.readWriteOncePodPVCs, - conflictingPVCRefCount: s.conflictingPVCRefCount, - } -} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *VolumeRestrictions) Name() string { - return Name -} - -func isVolumeConflict(volume *v1.Volume, pod *v1.Pod) bool { - for _, existingVolume := range pod.Spec.Volumes { - // Same GCE disk mounted by multiple pods conflicts unless all pods mount it read-only. - if volume.GCEPersistentDisk != nil && existingVolume.GCEPersistentDisk != nil { - disk, existingDisk := volume.GCEPersistentDisk, existingVolume.GCEPersistentDisk - if disk.PDName == existingDisk.PDName && !(disk.ReadOnly && existingDisk.ReadOnly) { - return true - } - } - - if volume.AWSElasticBlockStore != nil && existingVolume.AWSElasticBlockStore != nil { - if volume.AWSElasticBlockStore.VolumeID == existingVolume.AWSElasticBlockStore.VolumeID { - return true - } - } - - if volume.ISCSI != nil && existingVolume.ISCSI != nil { - iqn := volume.ISCSI.IQN - eiqn := existingVolume.ISCSI.IQN - // two ISCSI volumes are same, if they share the same iqn. As iscsi volumes are of type - // RWO or ROX, we could permit only one RW mount. Same iscsi volume mounted by multiple Pods - // conflict unless all other pods mount as read only. - if iqn == eiqn && !(volume.ISCSI.ReadOnly && existingVolume.ISCSI.ReadOnly) { - return true - } - } - - if volume.RBD != nil && existingVolume.RBD != nil { - mon, pool, image := volume.RBD.CephMonitors, volume.RBD.RBDPool, volume.RBD.RBDImage - emon, epool, eimage := existingVolume.RBD.CephMonitors, existingVolume.RBD.RBDPool, existingVolume.RBD.RBDImage - // two RBDs images are the same if they share the same Ceph monitor, are in the same RADOS Pool, and have the same image name - // only one read-write mount is permitted for the same RBD image. - // same RBD image mounted by multiple Pods conflicts unless all Pods mount the image read-only - if haveOverlap(mon, emon) && pool == epool && image == eimage && !(volume.RBD.ReadOnly && existingVolume.RBD.ReadOnly) { - return true - } - } - } - - return false -} - -// haveOverlap searches two arrays and returns true if they have at least one common element; returns false otherwise. -func haveOverlap(a1, a2 []string) bool { - if len(a1) > len(a2) { - a1, a2 = a2, a1 - } - m := sets.New(a1...) - for _, val := range a2 { - if _, ok := m[val]; ok { - return true - } - } - - return false -} - -// return true if there are conflict checking targets. -func needsRestrictionsCheck(v v1.Volume) bool { - return v.GCEPersistentDisk != nil || v.AWSElasticBlockStore != nil || v.RBD != nil || v.ISCSI != nil -} - -// PreFilter computes and stores cycleState containing details for enforcing ReadWriteOncePod. -func (pl *VolumeRestrictions) PreFilter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - needsCheck := false - for i := range pod.Spec.Volumes { - if needsRestrictionsCheck(pod.Spec.Volumes[i]) { - needsCheck = true - break - } - } - - pvcs, err := pl.readWriteOncePodPVCsForPod(ctx, pod) - if err != nil { - if apierrors.IsNotFound(err) { - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, err.Error()) - } - return nil, framework.AsStatus(err) - } - - s, err := pl.calPreFilterState(ctx, pod, pvcs) - if err != nil { - return nil, framework.AsStatus(err) - } - - if !needsCheck && s.conflictingPVCRefCount == 0 { - return nil, framework.NewStatus(framework.Skip) - } - cycleState.Write(preFilterStateKey, s) - return nil, nil -} - -// AddPod from pre-computed data in cycleState. -func (pl *VolumeRestrictions) AddPod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToAdd *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - state, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - state.updateWithPod(podInfoToAdd, 1) - return nil -} - -// RemovePod from pre-computed data in cycleState. -func (pl *VolumeRestrictions) RemovePod(ctx context.Context, cycleState *framework.CycleState, podToSchedule *v1.Pod, podInfoToRemove *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - state, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - state.updateWithPod(podInfoToRemove, -1) - return nil -} - -func getPreFilterState(cycleState *framework.CycleState) (*preFilterState, error) { - c, err := cycleState.Read(preFilterStateKey) - if err != nil { - // preFilterState doesn't exist, likely PreFilter wasn't invoked. - return nil, fmt.Errorf("cannot read %q from cycleState", preFilterStateKey) - } - - s, ok := c.(*preFilterState) - if !ok { - return nil, fmt.Errorf("%+v convert to volumerestrictions.state error", c) - } - return s, nil -} - -// calPreFilterState computes preFilterState describing which PVCs use ReadWriteOncePod -// and which pods in the cluster are in conflict. -func (pl *VolumeRestrictions) calPreFilterState(ctx context.Context, pod *v1.Pod, pvcs sets.Set[string]) (*preFilterState, error) { - conflictingPVCRefCount := 0 - for pvc := range pvcs { - key := framework.GetNamespacedName(pod.Namespace, pvc) - if pl.sharedLister.StorageInfos().IsPVCUsedByPods(key) { - // There can only be at most one pod using the ReadWriteOncePod PVC. - conflictingPVCRefCount += 1 - } - } - return &preFilterState{ - readWriteOncePodPVCs: pvcs, - conflictingPVCRefCount: conflictingPVCRefCount, - }, nil -} - -func (pl *VolumeRestrictions) readWriteOncePodPVCsForPod(ctx context.Context, pod *v1.Pod) (sets.Set[string], error) { - pvcs := sets.New[string]() - for _, volume := range pod.Spec.Volumes { - if volume.PersistentVolumeClaim == nil { - continue - } - - pvc, err := pl.pvcLister.PersistentVolumeClaims(pod.Namespace).Get(volume.PersistentVolumeClaim.ClaimName) - if err != nil { - return nil, err - } - - if !v1helper.ContainsAccessMode(pvc.Spec.AccessModes, v1.ReadWriteOncePod) { - continue - } - pvcs.Insert(pvc.Name) - } - return pvcs, nil -} - -// Checks if scheduling the pod onto this node would cause any conflicts with -// existing volumes. -func satisfyVolumeConflicts(pod *v1.Pod, nodeInfo *framework.NodeInfo) bool { - for i := range pod.Spec.Volumes { - v := pod.Spec.Volumes[i] - if !needsRestrictionsCheck(v) { - continue - } - for _, ev := range nodeInfo.Pods { - if isVolumeConflict(&v, ev.Pod) { - return false - } - } - } - return true -} - -// Checks if scheduling the pod would cause any ReadWriteOncePod PVC access mode conflicts. -func satisfyReadWriteOncePod(ctx context.Context, state *preFilterState) *framework.Status { - if state == nil { - return nil - } - if state.conflictingPVCRefCount > 0 { - return framework.NewStatus(framework.Unschedulable, ErrReasonReadWriteOncePodConflict) - } - return nil -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (pl *VolumeRestrictions) PreFilterExtensions() framework.PreFilterExtensions { - return pl -} - -// Filter invoked at the filter extension point. -// It evaluates if a pod can fit due to the volumes it requests, and those that -// are already mounted. If there is already a volume mounted on that node, another pod that uses the same volume -// can't be scheduled there. -// This is GCE, Amazon EBS, ISCSI and Ceph RBD specific for now: -// - GCE PD allows multiple mounts as long as they're all read-only -// - AWS EBS forbids any two pods mounting the same volume ID -// - Ceph RBD forbids if any two pods share at least same monitor, and match pool and image, and the image is read-only -// - ISCSI forbids if any two pods share at least same IQN and ISCSI volume is read-only -// If the pod uses PVCs with the ReadWriteOncePod access mode, it evaluates if -// these PVCs are already in-use and if preemption will help. -func (pl *VolumeRestrictions) Filter(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - if !satisfyVolumeConflicts(pod, nodeInfo) { - return framework.NewStatus(framework.Unschedulable, ErrReasonDiskConflict) - } - state, err := getPreFilterState(cycleState) - if err != nil { - return framework.AsStatus(err) - } - return satisfyReadWriteOncePod(ctx, state) -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *VolumeRestrictions) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // A note about UpdateNodeTaint/UpdateNodeLabel event: - // Ideally, it's supposed to register only Add because any Node update event will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeTaint | framework.UpdateNodeLabel - if pl.enableSchedulingQueueHint { - // preCheck is not used when QHint is enabled, and hence Update event isn't necessary. - nodeActionType = framework.Add - } - - return []framework.ClusterEventWithHint{ - // Pods may fail to schedule because of volumes conflicting with other pods on same node. - // Once running pods are deleted and volumes have been released, the unschedulable pod will be schedulable. - // Due to immutable fields `spec.volumes`, pod update events are ignored. - {Event: framework.ClusterEvent{Resource: framework.Pod, ActionType: framework.Delete}, QueueingHintFn: pl.isSchedulableAfterPodDeleted}, - // A new Node may make a pod schedulable. - // We intentionally don't set QueueingHint since all Node/Add events could make Pods schedulable. - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}}, - // Pods may fail to schedule because the PVC it uses has not yet been created. - // This PVC is required to exist to check its access modes. - {Event: framework.ClusterEvent{Resource: framework.PersistentVolumeClaim, ActionType: framework.Add}, - QueueingHintFn: pl.isSchedulableAfterPersistentVolumeClaimAdded}, - }, nil -} - -// isSchedulableAfterPersistentVolumeClaimAdded is invoked whenever a PersistentVolumeClaim added or changed, It checks whether -// that change made a previously unschedulable pod schedulable. -func (pl *VolumeRestrictions) isSchedulableAfterPersistentVolumeClaimAdded(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, newPersistentVolumeClaim, err := util.As[*v1.PersistentVolumeClaim](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterPersistentVolumeClaimChange: %w", err) - } - - if newPersistentVolumeClaim.Namespace != pod.Namespace { - return framework.QueueSkip, nil - } - - for _, volume := range pod.Spec.Volumes { - if volume.PersistentVolumeClaim == nil { - continue - } - - if volume.PersistentVolumeClaim.ClaimName == newPersistentVolumeClaim.Name { - logger.V(5).Info("PVC that is referred from the pod was created, which might make this pod schedulable", "pod", klog.KObj(pod), "PVC", klog.KObj(newPersistentVolumeClaim)) - return framework.Queue, nil - } - } - logger.V(5).Info("PVC irrelevant to the Pod was created, which doesn't make this pod schedulable", "pod", klog.KObj(pod), "PVC", klog.KObj(newPersistentVolumeClaim)) - return framework.QueueSkip, nil -} - -// isSchedulableAfterPodDeleted is invoked whenever a pod deleted, -// It checks whether the deleted pod will conflict with volumes of other pods on the same node -func (pl *VolumeRestrictions) isSchedulableAfterPodDeleted(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - deletedPod, _, err := util.As[*v1.Pod](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterPodDeleted: %w", err) - } - - if deletedPod.Namespace != pod.Namespace { - return framework.QueueSkip, nil - } - - nodeInfo := framework.NewNodeInfo(deletedPod) - if !satisfyVolumeConflicts(pod, nodeInfo) { - logger.V(5).Info("Pod with the volume that the target pod requires was deleted, which might make this pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(deletedPod)) - return framework.Queue, nil - } - - // Return Queue if a deleted pod uses the same PVC since the pod may be unschedulable due to the ReadWriteOncePod access mode of the PVC. - // - // For now, we don't actually fetch PVC and check the access mode because that operation could be expensive. - // Once the observability around QHint is established, - // we may want to do that depending on how much the operation would impact the QHint latency negatively. - // https://github.com/kubernetes/kubernetes/issues/124566 - claims := sets.New[string]() - for _, volume := range pod.Spec.Volumes { - if volume.PersistentVolumeClaim != nil { - claims.Insert(volume.PersistentVolumeClaim.ClaimName) - } - } - for _, volume := range deletedPod.Spec.Volumes { - if volume.PersistentVolumeClaim != nil && claims.Has(volume.PersistentVolumeClaim.ClaimName) { - logger.V(5).Info("Pod with the same PVC that the target pod requires was deleted, which might make this pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(deletedPod)) - return framework.Queue, nil - } - } - - logger.V(5).Info("An irrelevant Pod was deleted, which doesn't make this pod schedulable", "pod", klog.KObj(pod), "deletedPod", klog.KObj(deletedPod)) - return framework.QueueSkip, nil -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, handle framework.Handle, fts feature.Features) (framework.Plugin, error) { - informerFactory := handle.SharedInformerFactory() - pvcLister := informerFactory.Core().V1().PersistentVolumeClaims().Lister() - sharedLister := handle.SnapshotSharedLister() - - return &VolumeRestrictions{ - pvcLister: pvcLister, - sharedLister: sharedLister, - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - }, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/OWNERS b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/OWNERS deleted file mode 100644 index be3245e85..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - sig-storage-approvers - - cofyc -reviewers: - - sig-storage-reviewers - - cofyc -labels: - - sig/storage diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/volume_zone.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/volume_zone.go deleted file mode 100644 index ec39f2ef7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone/volume_zone.go +++ /dev/null @@ -1,410 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package volumezone - -import ( - "context" - "errors" - "fmt" - "reflect" - - v1 "k8s.io/api/core/v1" - storage "k8s.io/api/storage/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/sets" - corelisters "k8s.io/client-go/listers/core/v1" - storagelisters "k8s.io/client-go/listers/storage/v1" - volumehelpers "k8s.io/cloud-provider/volume/helpers" - storagehelpers "k8s.io/component-helpers/storage/volume" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/names" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// VolumeZone is a plugin that checks volume zone. -type VolumeZone struct { - pvLister corelisters.PersistentVolumeLister - pvcLister corelisters.PersistentVolumeClaimLister - scLister storagelisters.StorageClassLister - enableSchedulingQueueHint bool -} - -var _ framework.FilterPlugin = &VolumeZone{} -var _ framework.PreFilterPlugin = &VolumeZone{} -var _ framework.EnqueueExtensions = &VolumeZone{} - -const ( - // Name is the name of the plugin used in the plugin registry and configurations. - Name = names.VolumeZone - - preFilterStateKey framework.StateKey = "PreFilter" + Name - - // ErrReasonConflict is used for NoVolumeZoneConflict predicate error. - ErrReasonConflict = "node(s) had no available volume zone" -) - -// pvTopology holds the value of a pv's topologyLabel -type pvTopology struct { - pvName string - key string - values sets.Set[string] -} - -// the state is initialized in PreFilter phase. because we save the pointer in -// framework.CycleState, in the later phases we don't need to call Write method -// to update the value -type stateData struct { - // podPVTopologies holds the pv information we need - // it's initialized in the PreFilter phase - podPVTopologies []pvTopology -} - -func (d *stateData) Clone() framework.StateData { - return d -} - -var topologyLabels = []string{ - v1.LabelFailureDomainBetaZone, - v1.LabelFailureDomainBetaRegion, - v1.LabelTopologyZone, - v1.LabelTopologyRegion, -} - -func translateToGALabel(label string) string { - if label == v1.LabelFailureDomainBetaRegion { - return v1.LabelTopologyRegion - } - if label == v1.LabelFailureDomainBetaZone { - return v1.LabelTopologyZone - } - return label -} - -// Name returns name of the plugin. It is used in logs, etc. -func (pl *VolumeZone) Name() string { - return Name -} - -// PreFilter invoked at the prefilter extension point -// -// # It finds the topology of the PersistentVolumes corresponding to the volumes a pod requests -// -// Currently, this is only supported with PersistentVolumeClaims, -// and only looks for the bound PersistentVolume. -func (pl *VolumeZone) PreFilter(ctx context.Context, cs *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - logger := klog.FromContext(ctx) - podPVTopologies, status := pl.getPVbyPod(logger, pod) - if !status.IsSuccess() { - return nil, status - } - if len(podPVTopologies) == 0 { - return nil, framework.NewStatus(framework.Skip) - } - cs.Write(preFilterStateKey, &stateData{podPVTopologies: podPVTopologies}) - return nil, nil -} - -// getPVbyPod gets PVTopology from pod -func (pl *VolumeZone) getPVbyPod(logger klog.Logger, pod *v1.Pod) ([]pvTopology, *framework.Status) { - podPVTopologies := make([]pvTopology, 0) - - pvcNames := pl.getPersistentVolumeClaimNameFromPod(pod) - for _, pvcName := range pvcNames { - if pvcName == "" { - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, "PersistentVolumeClaim had no name") - } - pvc, err := pl.pvcLister.PersistentVolumeClaims(pod.Namespace).Get(pvcName) - if s := getErrorAsStatus(err); !s.IsSuccess() { - return nil, s - } - - pvName := pvc.Spec.VolumeName - if pvName == "" { - scName := storagehelpers.GetPersistentVolumeClaimClass(pvc) - if len(scName) == 0 { - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, "PersistentVolumeClaim had no pv name and storageClass name") - } - - class, err := pl.scLister.Get(scName) - if s := getErrorAsStatus(err); !s.IsSuccess() { - return nil, s - } - if class.VolumeBindingMode == nil { - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, fmt.Sprintf("VolumeBindingMode not set for StorageClass %q", scName)) - } - if *class.VolumeBindingMode == storage.VolumeBindingWaitForFirstConsumer { - // Skip unbound volumes - continue - } - - return nil, framework.NewStatus(framework.UnschedulableAndUnresolvable, "PersistentVolume had no name") - } - - pv, err := pl.pvLister.Get(pvName) - if s := getErrorAsStatus(err); !s.IsSuccess() { - return nil, s - } - podPVTopologies = append(podPVTopologies, pl.getPVTopologies(logger, pv)...) - } - return podPVTopologies, nil -} - -// PreFilterExtensions returns prefilter extensions, pod add and remove. -func (pl *VolumeZone) PreFilterExtensions() framework.PreFilterExtensions { - return nil -} - -// Filter invoked at the filter extension point. -// -// It evaluates if a pod can fit due to the volumes it requests, given -// that some volumes may have zone scheduling constraints. The requirement is that any -// volume zone-labels must match the equivalent zone-labels on the node. It is OK for -// the node to have more zone-label constraints (for example, a hypothetical replicated -// volume might allow region-wide access) -// -// Currently this is only supported with PersistentVolumeClaims, and looks to the labels -// only on the bound PersistentVolume. -// -// Working with volumes declared inline in the pod specification (i.e. not -// using a PersistentVolume) is likely to be harder, as it would require -// determining the zone of a volume during scheduling, and that is likely to -// require calling out to the cloud provider. It seems that we are moving away -// from inline volume declarations anyway. -func (pl *VolumeZone) Filter(ctx context.Context, cs *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - logger := klog.FromContext(ctx) - // If a pod doesn't have any volume attached to it, the predicate will always be true. - // Thus we make a fast path for it, to avoid unnecessary computations in this case. - if len(pod.Spec.Volumes) == 0 { - return nil - } - var podPVTopologies []pvTopology - state, err := getStateData(cs) - if err != nil { - // Fallback to calculate pv list here - var status *framework.Status - podPVTopologies, status = pl.getPVbyPod(logger, pod) - if !status.IsSuccess() { - return status - } - } else { - podPVTopologies = state.podPVTopologies - } - - node := nodeInfo.Node() - hasAnyNodeConstraint := false - for _, topologyLabel := range topologyLabels { - if _, ok := node.Labels[topologyLabel]; ok { - hasAnyNodeConstraint = true - break - } - } - - if !hasAnyNodeConstraint { - // The node has no zone constraints, so we're OK to schedule. - // This is to handle a single-zone cluster scenario where the node may not have any topology labels. - return nil - } - - for _, pvTopology := range podPVTopologies { - v, ok := node.Labels[pvTopology.key] - if !ok { - // if we can't match the beta label, try to match pv's beta label with node's ga label - v, ok = node.Labels[translateToGALabel(pvTopology.key)] - } - if !ok || !pvTopology.values.Has(v) { - logger.V(10).Info("Won't schedule pod onto node due to volume (mismatch on label key)", "pod", klog.KObj(pod), "node", klog.KObj(node), "PV", klog.KRef("", pvTopology.pvName), "PVLabelKey", pvTopology.key) - return framework.NewStatus(framework.UnschedulableAndUnresolvable, ErrReasonConflict) - } - } - - return nil -} - -func getStateData(cs *framework.CycleState) (*stateData, error) { - state, err := cs.Read(preFilterStateKey) - if err != nil { - return nil, err - } - s, ok := state.(*stateData) - if !ok { - return nil, errors.New("unable to convert state into stateData") - } - return s, nil -} - -func getErrorAsStatus(err error) *framework.Status { - if err != nil { - if apierrors.IsNotFound(err) { - return framework.NewStatus(framework.UnschedulableAndUnresolvable, err.Error()) - } - return framework.AsStatus(err) - } - return nil -} - -// EventsToRegister returns the possible events that may make a Pod -// failed by this plugin schedulable. -func (pl *VolumeZone) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // A new node or updating a node's volume zone labels may make a pod schedulable. - // A note about UpdateNodeTaint event: - // Ideally, it's supposed to register only Add | UpdateNodeLabel because UpdateNodeTaint will never change the result from this plugin. - // But, we may miss Node/Add event due to preCheck, and we decided to register UpdateNodeTaint | UpdateNodeLabel for all plugins registering Node/Add. - // See: https://github.com/kubernetes/kubernetes/issues/109437 - nodeActionType := framework.Add | framework.UpdateNodeLabel | framework.UpdateNodeTaint - if pl.enableSchedulingQueueHint { - // preCheck is not used when QHint is enabled. - nodeActionType = framework.Add | framework.UpdateNodeLabel - } - - return []framework.ClusterEventWithHint{ - // New storageClass with bind mode `VolumeBindingWaitForFirstConsumer` will make a pod schedulable. - // Due to immutable field `storageClass.volumeBindingMode`, storageClass update events are ignored. - {Event: framework.ClusterEvent{Resource: framework.StorageClass, ActionType: framework.Add}, QueueingHintFn: pl.isSchedulableAfterStorageClassAdded}, - {Event: framework.ClusterEvent{Resource: framework.Node, ActionType: nodeActionType}}, - // A new pvc may make a pod schedulable. - // Also, if pvc's VolumeName is filled, that also could make a pod schedulable. - {Event: framework.ClusterEvent{Resource: framework.PersistentVolumeClaim, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterPersistentVolumeClaimChange}, - // A new pv or updating a pv's volume zone labels may make a pod schedulable. - {Event: framework.ClusterEvent{Resource: framework.PersistentVolume, ActionType: framework.Add | framework.Update}, QueueingHintFn: pl.isSchedulableAfterPersistentVolumeChange}, - }, nil -} - -// getPersistentVolumeClaimNameFromPod gets pvc names bound to a pod. -func (pl *VolumeZone) getPersistentVolumeClaimNameFromPod(pod *v1.Pod) []string { - var pvcNames []string - for i := range pod.Spec.Volumes { - volume := pod.Spec.Volumes[i] - if volume.PersistentVolumeClaim == nil { - continue - } - pvcName := volume.PersistentVolumeClaim.ClaimName - pvcNames = append(pvcNames, pvcName) - } - return pvcNames -} - -// isSchedulableAfterPersistentVolumeClaimChange is invoked whenever a PersistentVolumeClaim added or updated. -// It checks whether the change of PVC has made a previously unschedulable pod schedulable. -func (pl *VolumeZone) isSchedulableAfterPersistentVolumeClaimChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, modifiedPVC, err := util.As[*v1.PersistentVolumeClaim](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterPersistentVolumeClaimChange: %w", err) - } - if pl.isPVCRequestedFromPod(logger, modifiedPVC, pod) { - logger.V(5).Info("PVC that is referred from the pod was created or updated, which might make this pod schedulable", "pod", klog.KObj(pod), "PVC", klog.KObj(modifiedPVC)) - return framework.Queue, nil - } - - logger.V(5).Info("PVC irrelevant to the Pod was created or updated, which doesn't make this pod schedulable", "pod", klog.KObj(pod), "PVC", klog.KObj(modifiedPVC)) - return framework.QueueSkip, nil -} - -// isPVCRequestedFromPod verifies if the PVC is requested from a given Pod. -func (pl *VolumeZone) isPVCRequestedFromPod(logger klog.Logger, pvc *v1.PersistentVolumeClaim, pod *v1.Pod) bool { - if (pvc == nil) || (pod.Namespace != pvc.Namespace) { - return false - } - pvcNames := pl.getPersistentVolumeClaimNameFromPod(pod) - for _, pvcName := range pvcNames { - if pvc.Name == pvcName { - logger.V(5).Info("PVC is referred from the pod", "pod", klog.KObj(pod), "PVC", klog.KObj(pvc)) - return true - } - } - logger.V(5).Info("PVC is not referred from the pod", "pod", klog.KObj(pod), "PVC", klog.KObj(pvc)) - return false -} - -// isSchedulableAfterStorageClassAdded is invoked whenever a StorageClass is added. -// It checks whether the addition of StorageClass has made a previously unschedulable pod schedulable. -// Only a new StorageClass with WaitForFirstConsumer will cause a pod to become schedulable. -func (pl *VolumeZone) isSchedulableAfterStorageClassAdded(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - _, addedStorageClass, err := util.As[*storage.StorageClass](nil, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterStorageClassAdded: %w", err) - } - if (addedStorageClass.VolumeBindingMode == nil) || (*addedStorageClass.VolumeBindingMode != storage.VolumeBindingWaitForFirstConsumer) { - logger.V(5).Info("StorageClass is created, but its VolumeBindingMode is not waitForFirstConsumer, which doesn't make the pod schedulable", "storageClass", klog.KObj(addedStorageClass), "pod", klog.KObj(pod)) - return framework.QueueSkip, nil - } - - logger.V(5).Info("StorageClass with waitForFirstConsumer mode was created and it might make this pod schedulable", "pod", klog.KObj(pod), "StorageClass", klog.KObj(addedStorageClass)) - return framework.Queue, nil -} - -// isSchedulableAfterPersistentVolumeChange is invoked whenever a PersistentVolume added or updated. -// It checks whether the change of PV has made a previously unschedulable pod schedulable. -// Changing the PV topology labels could cause the pod to become schedulable. -func (pl *VolumeZone) isSchedulableAfterPersistentVolumeChange(logger klog.Logger, pod *v1.Pod, oldObj, newObj interface{}) (framework.QueueingHint, error) { - originalPV, modifiedPV, err := util.As[*v1.PersistentVolume](oldObj, newObj) - if err != nil { - return framework.Queue, fmt.Errorf("unexpected objects in isSchedulableAfterPersistentVolumeChange: %w", err) - } - if originalPV == nil { - logger.V(5).Info("PV is newly created, which might make the pod schedulable") - return framework.Queue, nil - } - originalPVTopologies := pl.getPVTopologies(logger, originalPV) - modifiedPVTopologies := pl.getPVTopologies(logger, modifiedPV) - if !reflect.DeepEqual(originalPVTopologies, modifiedPVTopologies) { - logger.V(5).Info("PV's topology was updated, which might make the pod schedulable.", "pod", klog.KObj(pod), "PV", klog.KObj(modifiedPV)) - return framework.Queue, nil - } - - logger.V(5).Info("PV was updated, but the topology is unchanged, which it doesn't make the pod schedulable", "pod", klog.KObj(pod), "PV", klog.KObj(modifiedPV)) - return framework.QueueSkip, nil -} - -// getPVTopologies retrieves pvTopology from a given PV and returns the array -// This function doesn't check spec.nodeAffinity -// because it's read-only after creation and thus cannot be updated -// and nodeAffinity is being handled in node affinity plugin -func (pl *VolumeZone) getPVTopologies(logger klog.Logger, pv *v1.PersistentVolume) []pvTopology { - podPVTopologies := make([]pvTopology, 0) - for _, key := range topologyLabels { - if value, ok := pv.ObjectMeta.Labels[key]; ok { - labelZonesSet, err := volumehelpers.LabelZonesToSet(value) - if err != nil { - logger.V(5).Info("failed to parse PV's topology label, ignoring the label", "label", fmt.Sprintf("%s:%s", key, value), "err", err) - continue - } - podPVTopologies = append(podPVTopologies, pvTopology{ - pvName: pv.Name, - key: key, - values: sets.Set[string](labelZonesSet), - }) - } - } - return podPVTopologies -} - -// New initializes a new plugin and returns it. -func New(_ context.Context, _ runtime.Object, handle framework.Handle, fts feature.Features) (framework.Plugin, error) { - informerFactory := handle.SharedInformerFactory() - pvLister := informerFactory.Core().V1().PersistentVolumes().Lister() - pvcLister := informerFactory.Core().V1().PersistentVolumeClaims().Lister() - scLister := informerFactory.Storage().V1().StorageClasses().Lister() - return &VolumeZone{ - pvLister: pvLister, - pvcLister: pvcLister, - scLister: scLister, - enableSchedulingQueueHint: fts.EnableSchedulingQueueHint, - }, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go deleted file mode 100644 index d23c18595..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/preemption/preemption.go +++ /dev/null @@ -1,739 +0,0 @@ -/* -Copyright 2021 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package preemption - -import ( - "context" - "errors" - "fmt" - "math" - "sync" - "sync/atomic" - "time" - - v1 "k8s.io/api/core/v1" - policy "k8s.io/api/policy/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/types" - utilerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - corelisters "k8s.io/client-go/listers/core/v1" - policylisters "k8s.io/client-go/listers/policy/v1" - corev1helpers "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/klog/v2" - extenderv1 "k8s.io/kube-scheduler/extender/v1" - apipod "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/scheduler/util" -) - -// Candidate represents a nominated node on which the preemptor can be scheduled, -// along with the list of victims that should be evicted for the preemptor to fit the node. -type Candidate interface { - // Victims wraps a list of to-be-preempted Pods and the number of PDB violation. - Victims() *extenderv1.Victims - // Name returns the target node name where the preemptor gets nominated to run. - Name() string -} - -type candidate struct { - victims *extenderv1.Victims - name string -} - -// Victims returns s.victims. -func (s *candidate) Victims() *extenderv1.Victims { - return s.victims -} - -// Name returns s.name. -func (s *candidate) Name() string { - return s.name -} - -type candidateList struct { - idx int32 - items []Candidate -} - -func newCandidateList(size int32) *candidateList { - return &candidateList{idx: -1, items: make([]Candidate, size)} -} - -// add adds a new candidate to the internal array atomically. -func (cl *candidateList) add(c *candidate) { - if idx := atomic.AddInt32(&cl.idx, 1); idx < int32(len(cl.items)) { - cl.items[idx] = c - } -} - -// size returns the number of candidate stored. Note that some add() operations -// might still be executing when this is called, so care must be taken to -// ensure that all add() operations complete before accessing the elements of -// the list. -func (cl *candidateList) size() int32 { - n := atomic.LoadInt32(&cl.idx) + 1 - if n >= int32(len(cl.items)) { - n = int32(len(cl.items)) - } - return n -} - -// get returns the internal candidate array. This function is NOT atomic and -// assumes that all add() operations have been completed. -func (cl *candidateList) get() []Candidate { - return cl.items[:cl.size()] -} - -// Interface is expected to be implemented by different preemption plugins as all those member -// methods might have different behavior compared with the default preemption. -type Interface interface { - // GetOffsetAndNumCandidates chooses a random offset and calculates the number of candidates that should be - // shortlisted for dry running preemption. - GetOffsetAndNumCandidates(nodes int32) (int32, int32) - // CandidatesToVictimsMap builds a map from the target node to a list of to-be-preempted Pods and the number of PDB violation. - CandidatesToVictimsMap(candidates []Candidate) map[string]*extenderv1.Victims - // PodEligibleToPreemptOthers returns one bool and one string. The bool indicates whether this pod should be considered for - // preempting other pods or not. The string includes the reason if this pod isn't eligible. - PodEligibleToPreemptOthers(ctx context.Context, pod *v1.Pod, nominatedNodeStatus *framework.Status) (bool, string) - // SelectVictimsOnNode finds minimum set of pods on the given node that should be preempted in order to make enough room - // for "pod" to be scheduled. - // Note that both `state` and `nodeInfo` are deep copied. - SelectVictimsOnNode(ctx context.Context, state *framework.CycleState, - pod *v1.Pod, nodeInfo *framework.NodeInfo, pdbs []*policy.PodDisruptionBudget) ([]*v1.Pod, int, *framework.Status) - // OrderedScoreFuncs returns a list of ordered score functions to select preferable node where victims will be preempted. - // The ordered score functions will be processed one by one iff we find more than one node with the highest score. - // Default score functions will be processed if nil returned here for backwards-compatibility. - OrderedScoreFuncs(ctx context.Context, nodesToVictims map[string]*extenderv1.Victims) []func(node string) int64 -} - -type Evaluator struct { - PluginName string - Handler framework.Handle - PodLister corelisters.PodLister - PdbLister policylisters.PodDisruptionBudgetLister - - enableAsyncPreemption bool - mu sync.RWMutex - // preempting is a set that records the pods that are currently triggering preemption asynchronously, - // which is used to prevent the pods from entering the scheduling cycle meanwhile. - preempting sets.Set[types.UID] - - // PreemptPod is a function that actually makes API calls to preempt a specific Pod. - // This is exposed to be replaced during tests. - PreemptPod func(ctx context.Context, c Candidate, preemptor, victim *v1.Pod, pluginName string) error - - Interface -} - -func NewEvaluator(pluginName string, fh framework.Handle, i Interface, enableAsyncPreemption bool) *Evaluator { - podLister := fh.SharedInformerFactory().Core().V1().Pods().Lister() - pdbLister := fh.SharedInformerFactory().Policy().V1().PodDisruptionBudgets().Lister() - - ev := &Evaluator{ - PluginName: pluginName, - Handler: fh, - PodLister: podLister, - PdbLister: pdbLister, - Interface: i, - enableAsyncPreemption: enableAsyncPreemption, - preempting: sets.New[types.UID](), - } - - // PreemptPod actually makes API calls to preempt a specific Pod. - // - // We implement it here directly, rather than creating a separate method like ev.preemptPod(...) - // to prevent the misuse of the PreemptPod function. - ev.PreemptPod = func(ctx context.Context, c Candidate, preemptor, victim *v1.Pod, pluginName string) error { - logger := klog.FromContext(ctx) - - // If the victim is a WaitingPod, send a reject message to the PermitPlugin. - // Otherwise we should delete the victim. - if waitingPod := ev.Handler.GetWaitingPod(victim.UID); waitingPod != nil { - waitingPod.Reject(pluginName, "preempted") - logger.V(2).Info("Preemptor pod rejected a waiting pod", "preemptor", klog.KObj(preemptor), "waitingPod", klog.KObj(victim), "node", c.Name()) - } else { - condition := &v1.PodCondition{ - Type: v1.DisruptionTarget, - ObservedGeneration: apipod.GetPodObservedGenerationIfEnabledOnCondition(&victim.Status, victim.Generation, v1.DisruptionTarget), - Status: v1.ConditionTrue, - Reason: v1.PodReasonPreemptionByScheduler, - Message: fmt.Sprintf("%s: preempting to accommodate a higher priority pod", preemptor.Spec.SchedulerName), - } - newStatus := victim.Status.DeepCopy() - updated := apipod.UpdatePodCondition(newStatus, condition) - if updated { - if err := util.PatchPodStatus(ctx, ev.Handler.ClientSet(), victim, newStatus); err != nil { - logger.Error(err, "Could not add DisruptionTarget condition due to preemption", "pod", klog.KObj(victim), "preemptor", klog.KObj(preemptor)) - return err - } - } - if err := util.DeletePod(ctx, ev.Handler.ClientSet(), victim); err != nil { - if !apierrors.IsNotFound(err) { - logger.Error(err, "Tried to preempted pod", "pod", klog.KObj(victim), "preemptor", klog.KObj(preemptor)) - return err - } - logger.V(2).Info("Victim Pod is already deleted", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) - return nil - } - logger.V(2).Info("Preemptor Pod preempted victim Pod", "preemptor", klog.KObj(preemptor), "victim", klog.KObj(victim), "node", c.Name()) - } - - ev.Handler.EventRecorder().Eventf(victim, preemptor, v1.EventTypeNormal, "Preempted", "Preempting", "Preempted by pod %v on node %v", preemptor.UID, c.Name()) - - return nil - } - - return ev -} - -// IsPodRunningPreemption returns true if the pod is currently triggering preemption asynchronously. -func (ev *Evaluator) IsPodRunningPreemption(podUID types.UID) bool { - ev.mu.RLock() - defer ev.mu.RUnlock() - - return ev.preempting.Has(podUID) -} - -// Preempt returns a PostFilterResult carrying suggested nominatedNodeName, along with a Status. -// The semantics of returned varies on different scenarios: -// -// - . This denotes it's a transient/rare error that may be self-healed in future cycles. -// -// - . This status is mostly as expected like the preemptor is waiting for the -// victims to be fully terminated. -// -// - In both cases above, a nil PostFilterResult is returned to keep the pod's nominatedNodeName unchanged. -// -// - . It indicates the pod cannot be scheduled even with preemption. -// In this case, a non-nil PostFilterResult is returned and result.NominatingMode instructs how to deal with -// the nominatedNodeName. -// -// - . It's the regular happy path -// and the non-empty nominatedNodeName will be applied to the preemptor pod. -func (ev *Evaluator) Preempt(ctx context.Context, state *framework.CycleState, pod *v1.Pod, m framework.NodeToStatusReader) (*framework.PostFilterResult, *framework.Status) { - logger := klog.FromContext(ctx) - - // 0) Fetch the latest version of . - // It's safe to directly fetch pod here. Because the informer cache has already been - // initialized when creating the Scheduler obj. - // However, tests may need to manually initialize the shared pod informer. - podNamespace, podName := pod.Namespace, pod.Name - pod, err := ev.PodLister.Pods(pod.Namespace).Get(pod.Name) - if err != nil { - logger.Error(err, "Could not get the updated preemptor pod object", "pod", klog.KRef(podNamespace, podName)) - return nil, framework.AsStatus(err) - } - - // 1) Ensure the preemptor is eligible to preempt other pods. - nominatedNodeStatus := m.Get(pod.Status.NominatedNodeName) - if ok, msg := ev.PodEligibleToPreemptOthers(ctx, pod, nominatedNodeStatus); !ok { - logger.V(5).Info("Pod is not eligible for preemption", "pod", klog.KObj(pod), "reason", msg) - return nil, framework.NewStatus(framework.Unschedulable, msg) - } - - // 2) Find all preemption candidates. - allNodes, err := ev.Handler.SnapshotSharedLister().NodeInfos().List() - if err != nil { - return nil, framework.AsStatus(err) - } - candidates, nodeToStatusMap, err := ev.findCandidates(ctx, state, allNodes, pod, m) - if err != nil && len(candidates) == 0 { - return nil, framework.AsStatus(err) - } - - // Return a FitError only when there are no candidates that fit the pod. - if len(candidates) == 0 { - logger.V(2).Info("No preemption candidate is found; preemption is not helpful for scheduling", "pod", klog.KObj(pod)) - fitError := &framework.FitError{ - Pod: pod, - NumAllNodes: len(allNodes), - Diagnosis: framework.Diagnosis{ - NodeToStatus: nodeToStatusMap, - // Leave UnschedulablePlugins or PendingPlugins as nil as it won't be used on moving Pods. - }, - } - fitError.Diagnosis.NodeToStatus.SetAbsentNodesStatus(framework.NewStatus(framework.UnschedulableAndUnresolvable, "Preemption is not helpful for scheduling")) - // Specify nominatedNodeName to clear the pod's nominatedNodeName status, if applicable. - return framework.NewPostFilterResultWithNominatedNode(""), framework.NewStatus(framework.Unschedulable, fitError.Error()) - } - - // 3) Interact with registered Extenders to filter out some candidates if needed. - candidates, status := ev.callExtenders(logger, pod, candidates) - if !status.IsSuccess() { - return nil, status - } - - // 4) Find the best candidate. - bestCandidate := ev.SelectCandidate(ctx, candidates) - if bestCandidate == nil || len(bestCandidate.Name()) == 0 { - return nil, framework.NewStatus(framework.Unschedulable, "no candidate node for preemption") - } - - logger.V(2).Info("the target node for the preemption is determined", "node", bestCandidate.Name(), "pod", klog.KObj(pod)) - - // 5) Perform preparation work before nominating the selected candidate. - if ev.enableAsyncPreemption { - ev.prepareCandidateAsync(bestCandidate, pod, ev.PluginName) - } else { - if status := ev.prepareCandidate(ctx, bestCandidate, pod, ev.PluginName); !status.IsSuccess() { - return nil, status - } - } - - return framework.NewPostFilterResultWithNominatedNode(bestCandidate.Name()), framework.NewStatus(framework.Success) -} - -// FindCandidates calculates a slice of preemption candidates. -// Each candidate is executable to make the given schedulable. -func (ev *Evaluator) findCandidates(ctx context.Context, state *framework.CycleState, allNodes []*framework.NodeInfo, pod *v1.Pod, m framework.NodeToStatusReader) ([]Candidate, *framework.NodeToStatus, error) { - if len(allNodes) == 0 { - return nil, nil, errors.New("no nodes available") - } - logger := klog.FromContext(ctx) - // Get a list of nodes with failed predicates (Unschedulable) that may be satisfied by removing pods from the node. - potentialNodes, err := m.NodesForStatusCode(ev.Handler.SnapshotSharedLister().NodeInfos(), framework.Unschedulable) - if err != nil { - return nil, nil, err - } - if len(potentialNodes) == 0 { - logger.V(3).Info("Preemption will not help schedule pod on any node", "pod", klog.KObj(pod)) - // In this case, we should clean-up any existing nominated node name of the pod. - if err := util.ClearNominatedNodeName(ctx, ev.Handler.ClientSet(), pod); err != nil { - logger.Error(err, "Could not clear the nominatedNodeName field of pod", "pod", klog.KObj(pod)) - // We do not return as this error is not critical. - } - return nil, framework.NewDefaultNodeToStatus(), nil - } - - pdbs, err := getPodDisruptionBudgets(ev.PdbLister) - if err != nil { - return nil, nil, err - } - - offset, candidatesNum := ev.GetOffsetAndNumCandidates(int32(len(potentialNodes))) - return ev.DryRunPreemption(ctx, state, pod, potentialNodes, pdbs, offset, candidatesNum) -} - -// callExtenders calls given to select the list of feasible candidates. -// We will only check with extenders that support preemption. -// Extenders which do not support preemption may later prevent preemptor from being scheduled on the nominated -// node. In that case, scheduler will find a different host for the preemptor in subsequent scheduling cycles. -func (ev *Evaluator) callExtenders(logger klog.Logger, pod *v1.Pod, candidates []Candidate) ([]Candidate, *framework.Status) { - extenders := ev.Handler.Extenders() - nodeLister := ev.Handler.SnapshotSharedLister().NodeInfos() - if len(extenders) == 0 { - return candidates, nil - } - - // Migrate candidate slice to victimsMap to adapt to the Extender interface. - // It's only applicable for candidate slice that have unique nominated node name. - victimsMap := ev.CandidatesToVictimsMap(candidates) - if len(victimsMap) == 0 { - return candidates, nil - } - for _, extender := range extenders { - if !extender.SupportsPreemption() || !extender.IsInterested(pod) { - continue - } - nodeNameToVictims, err := extender.ProcessPreemption(pod, victimsMap, nodeLister) - if err != nil { - if extender.IsIgnorable() { - logger.Info("Skipped extender as it returned error and has ignorable flag set", - "extender", extender.Name(), "err", err) - continue - } - return nil, framework.AsStatus(err) - } - // Check if the returned victims are valid. - for nodeName, victims := range nodeNameToVictims { - if victims == nil || len(victims.Pods) == 0 { - if extender.IsIgnorable() { - delete(nodeNameToVictims, nodeName) - logger.Info("Ignored node for which the extender didn't report victims", "node", klog.KRef("", nodeName), "extender", extender.Name()) - continue - } - return nil, framework.AsStatus(fmt.Errorf("expected at least one victim pod on node %q", nodeName)) - } - } - - // Replace victimsMap with new result after preemption. So the - // rest of extenders can continue use it as parameter. - victimsMap = nodeNameToVictims - - // If node list becomes empty, no preemption can happen regardless of other extenders. - if len(victimsMap) == 0 { - break - } - } - - var newCandidates []Candidate - for nodeName := range victimsMap { - newCandidates = append(newCandidates, &candidate{ - victims: victimsMap[nodeName], - name: nodeName, - }) - } - return newCandidates, nil -} - -// SelectCandidate chooses the best-fit candidate from given and return it. -// NOTE: This method is exported for easier testing in default preemption. -func (ev *Evaluator) SelectCandidate(ctx context.Context, candidates []Candidate) Candidate { - logger := klog.FromContext(ctx) - - if len(candidates) == 0 { - return nil - } - if len(candidates) == 1 { - return candidates[0] - } - - victimsMap := ev.CandidatesToVictimsMap(candidates) - scoreFuncs := ev.OrderedScoreFuncs(ctx, victimsMap) - candidateNode := pickOneNodeForPreemption(logger, victimsMap, scoreFuncs) - - // Same as candidatesToVictimsMap, this logic is not applicable for out-of-tree - // preemption plugins that exercise different candidates on the same nominated node. - if victims := victimsMap[candidateNode]; victims != nil { - return &candidate{ - victims: victims, - name: candidateNode, - } - } - - // We shouldn't reach here. - logger.Error(errors.New("no candidate selected"), "Should not reach here", "candidates", candidates) - // To not break the whole flow, return the first candidate. - return candidates[0] -} - -// prepareCandidate does some preparation work before nominating the selected candidate: -// - Evict the victim pods -// - Reject the victim pods if they are in waitingPod map -// - Clear the low-priority pods' nominatedNodeName status if needed -func (ev *Evaluator) prepareCandidate(ctx context.Context, c Candidate, pod *v1.Pod, pluginName string) *framework.Status { - fh := ev.Handler - cs := ev.Handler.ClientSet() - - ctx, cancel := context.WithCancel(ctx) - defer cancel() - logger := klog.FromContext(ctx) - errCh := parallelize.NewErrorChannel() - fh.Parallelizer().Until(ctx, len(c.Victims().Pods), func(index int) { - if err := ev.PreemptPod(ctx, c, pod, c.Victims().Pods[index], pluginName); err != nil { - errCh.SendErrorWithCancel(err, cancel) - } - }, ev.PluginName) - if err := errCh.ReceiveError(); err != nil { - return framework.AsStatus(err) - } - - metrics.PreemptionVictims.Observe(float64(len(c.Victims().Pods))) - - // Lower priority pods nominated to run on this node, may no longer fit on - // this node. So, we should remove their nomination. Removing their - // nomination updates these pods and moves them to the active queue. It - // lets scheduler find another place for them. - nominatedPods := getLowerPriorityNominatedPods(logger, fh, pod, c.Name()) - if err := util.ClearNominatedNodeName(ctx, cs, nominatedPods...); err != nil { - logger.Error(err, "Cannot clear 'NominatedNodeName' field") - // We do not return as this error is not critical. - } - - return nil -} - -// prepareCandidateAsync triggers a goroutine for some preparation work: -// - Evict the victim pods -// - Reject the victim pods if they are in waitingPod map -// - Clear the low-priority pods' nominatedNodeName status if needed -// The Pod won't be retried until the goroutine triggered here completes. -// -// See http://kep.k8s.io/4832 for how the async preemption works. -func (ev *Evaluator) prepareCandidateAsync(c Candidate, pod *v1.Pod, pluginName string) { - metrics.PreemptionVictims.Observe(float64(len(c.Victims().Pods))) - - // Intentionally create a new context, not using a ctx from the scheduling cycle, to create ctx, - // because this process could continue even after this scheduling cycle finishes. - ctx, cancel := context.WithCancel(context.Background()) - errCh := parallelize.NewErrorChannel() - preemptPod := func(index int) { - victim := c.Victims().Pods[index] - if err := ev.PreemptPod(ctx, c, pod, victim, pluginName); err != nil { - errCh.SendErrorWithCancel(err, cancel) - } - } - - ev.mu.Lock() - ev.preempting.Insert(pod.UID) - ev.mu.Unlock() - - logger := klog.FromContext(ctx) - go func() { - startTime := time.Now() - result := metrics.GoroutineResultSuccess - defer metrics.PreemptionGoroutinesDuration.WithLabelValues(result).Observe(metrics.SinceInSeconds(startTime)) - defer metrics.PreemptionGoroutinesExecutionTotal.WithLabelValues(result).Inc() - defer func() { - if result == metrics.GoroutineResultError { - // When API call isn't successful, the Pod may get stuck in the unschedulable pod pool in the worst case. - // So, we should move the Pod to the activeQ. - ev.Handler.Activate(logger, map[string]*v1.Pod{pod.Name: pod}) - } - }() - defer cancel() - logger.V(2).Info("Start the preemption asynchronously", "preemptor", klog.KObj(pod), "node", c.Name(), "numVictims", len(c.Victims().Pods)) - - // Lower priority pods nominated to run on this node, may no longer fit on - // this node. So, we should remove their nomination. Removing their - // nomination updates these pods and moves them to the active queue. It - // lets scheduler find another place for them. - nominatedPods := getLowerPriorityNominatedPods(logger, ev.Handler, pod, c.Name()) - if err := util.ClearNominatedNodeName(ctx, ev.Handler.ClientSet(), nominatedPods...); err != nil { - logger.Error(err, "Cannot clear 'NominatedNodeName' field from lower priority pods on the same target node", "node", c.Name()) - result = metrics.GoroutineResultError - // We do not return as this error is not critical. - } - - if len(c.Victims().Pods) == 0 { - ev.mu.Lock() - delete(ev.preempting, pod.UID) - ev.mu.Unlock() - - return - } - - // We can evict all victims in parallel, but the last one. - // We have to remove the pod from the preempting map before the last one is evicted - // because, otherwise, the pod removal might be notified to the scheduling queue before - // we remove this pod from the preempting map, - // and the pod could end up stucking at the unschedulable pod pool - // by all the pod removal events being ignored. - ev.Handler.Parallelizer().Until(ctx, len(c.Victims().Pods)-1, preemptPod, ev.PluginName) - if err := errCh.ReceiveError(); err != nil { - logger.Error(err, "Error occurred during async preemption") - result = metrics.GoroutineResultError - } - - ev.mu.Lock() - delete(ev.preempting, pod.UID) - ev.mu.Unlock() - - if err := ev.PreemptPod(ctx, c, pod, c.Victims().Pods[len(c.Victims().Pods)-1], pluginName); err != nil { - logger.Error(err, "Error occurred during async preemption") - result = metrics.GoroutineResultError - } - - logger.V(2).Info("Async Preemption finished completely", "preemptor", klog.KObj(pod), "node", c.Name(), "result", result) - }() -} - -func getPodDisruptionBudgets(pdbLister policylisters.PodDisruptionBudgetLister) ([]*policy.PodDisruptionBudget, error) { - if pdbLister != nil { - return pdbLister.List(labels.Everything()) - } - return nil, nil -} - -// pickOneNodeForPreemption chooses one node among the given nodes. -// It assumes pods in each map entry are ordered by decreasing priority. -// If the scoreFuns is not empty, It picks a node based on score scoreFuns returns. -// If the scoreFuns is empty, -// It picks a node based on the following criteria: -// 1. A node with minimum number of PDB violations. -// 2. A node with minimum highest priority victim is picked. -// 3. Ties are broken by sum of priorities of all victims. -// 4. If there are still ties, node with the minimum number of victims is picked. -// 5. If there are still ties, node with the latest start time of all highest priority victims is picked. -// 6. If there are still ties, the first such node is picked (sort of randomly). -// The 'minNodes1' and 'minNodes2' are being reused here to save the memory -// allocation and garbage collection time. -func pickOneNodeForPreemption(logger klog.Logger, nodesToVictims map[string]*extenderv1.Victims, scoreFuncs []func(node string) int64) string { - if len(nodesToVictims) == 0 { - return "" - } - - allCandidates := make([]string, 0, len(nodesToVictims)) - for node := range nodesToVictims { - allCandidates = append(allCandidates, node) - } - - if len(scoreFuncs) == 0 { - minNumPDBViolatingScoreFunc := func(node string) int64 { - // The smaller the NumPDBViolations, the higher the score. - return -nodesToVictims[node].NumPDBViolations - } - minHighestPriorityScoreFunc := func(node string) int64 { - // highestPodPriority is the highest priority among the victims on this node. - highestPodPriority := corev1helpers.PodPriority(nodesToVictims[node].Pods[0]) - // The smaller the highestPodPriority, the higher the score. - return -int64(highestPodPriority) - } - minSumPrioritiesScoreFunc := func(node string) int64 { - var sumPriorities int64 - for _, pod := range nodesToVictims[node].Pods { - // We add MaxInt32+1 to all priorities to make all of them >= 0. This is - // needed so that a node with a few pods with negative priority is not - // picked over a node with a smaller number of pods with the same negative - // priority (and similar scenarios). - sumPriorities += int64(corev1helpers.PodPriority(pod)) + int64(math.MaxInt32+1) - } - // The smaller the sumPriorities, the higher the score. - return -sumPriorities - } - minNumPodsScoreFunc := func(node string) int64 { - // The smaller the length of pods, the higher the score. - return -int64(len(nodesToVictims[node].Pods)) - } - latestStartTimeScoreFunc := func(node string) int64 { - // Get the earliest start time of all pods on the current node. - earliestStartTimeOnNode := util.GetEarliestPodStartTime(nodesToVictims[node]) - if earliestStartTimeOnNode == nil { - logger.Error(errors.New("earliestStartTime is nil for node"), "Should not reach here", "node", node) - return int64(math.MinInt64) - } - // The bigger the earliestStartTimeOnNode, the higher the score. - return earliestStartTimeOnNode.UnixNano() - } - - // Each scoreFunc scores the nodes according to specific rules and keeps the name of the node - // with the highest score. If and only if the scoreFunc has more than one node with the highest - // score, we will execute the other scoreFunc in order of precedence. - scoreFuncs = []func(string) int64{ - // A node with a minimum number of PDB is preferable. - minNumPDBViolatingScoreFunc, - // A node with a minimum highest priority victim is preferable. - minHighestPriorityScoreFunc, - // A node with the smallest sum of priorities is preferable. - minSumPrioritiesScoreFunc, - // A node with the minimum number of pods is preferable. - minNumPodsScoreFunc, - // A node with the latest start time of all highest priority victims is preferable. - latestStartTimeScoreFunc, - // If there are still ties, then the first Node in the list is selected. - } - } - - for _, f := range scoreFuncs { - selectedNodes := []string{} - maxScore := int64(math.MinInt64) - for _, node := range allCandidates { - score := f(node) - if score > maxScore { - maxScore = score - selectedNodes = []string{} - } - if score == maxScore { - selectedNodes = append(selectedNodes, node) - } - } - if len(selectedNodes) == 1 { - return selectedNodes[0] - } - allCandidates = selectedNodes - } - - return allCandidates[0] -} - -// getLowerPriorityNominatedPods returns pods whose priority is smaller than the -// priority of the given "pod" and are nominated to run on the given node. -// Note: We could possibly check if the nominated lower priority pods still fit -// and return those that no longer fit, but that would require lots of -// manipulation of NodeInfo and PreFilter state per nominated pod. It may not be -// worth the complexity, especially because we generally expect to have a very -// small number of nominated pods per node. -func getLowerPriorityNominatedPods(logger klog.Logger, pn framework.PodNominator, pod *v1.Pod, nodeName string) []*v1.Pod { - podInfos := pn.NominatedPodsForNode(nodeName) - - if len(podInfos) == 0 { - return nil - } - - var lowerPriorityPods []*v1.Pod - podPriority := corev1helpers.PodPriority(pod) - for _, pi := range podInfos { - if corev1helpers.PodPriority(pi.Pod) < podPriority { - lowerPriorityPods = append(lowerPriorityPods, pi.Pod) - } - } - return lowerPriorityPods -} - -// DryRunPreemption simulates Preemption logic on in parallel, -// returns preemption candidates and a map indicating filtered nodes statuses. -// The number of candidates depends on the constraints defined in the plugin's args. In the returned list of -// candidates, ones that do not violate PDB are preferred over ones that do. -// NOTE: This method is exported for easier testing in default preemption. -func (ev *Evaluator) DryRunPreemption(ctx context.Context, state *framework.CycleState, pod *v1.Pod, potentialNodes []*framework.NodeInfo, - pdbs []*policy.PodDisruptionBudget, offset int32, candidatesNum int32) ([]Candidate, *framework.NodeToStatus, error) { - - fh := ev.Handler - nonViolatingCandidates := newCandidateList(candidatesNum) - violatingCandidates := newCandidateList(candidatesNum) - ctx, cancel := context.WithCancel(ctx) - defer cancel() - nodeStatuses := framework.NewDefaultNodeToStatus() - - logger := klog.FromContext(ctx) - logger.V(5).Info("Dry run the preemption", "potentialNodesNumber", len(potentialNodes), "pdbsNumber", len(pdbs), "offset", offset, "candidatesNumber", candidatesNum) - - var statusesLock sync.Mutex - var errs []error - checkNode := func(i int) { - nodeInfoCopy := potentialNodes[(int(offset)+i)%len(potentialNodes)].Snapshot() - logger.V(5).Info("Check the potential node for preemption", "node", nodeInfoCopy.Node().Name) - - stateCopy := state.Clone() - pods, numPDBViolations, status := ev.SelectVictimsOnNode(ctx, stateCopy, pod, nodeInfoCopy, pdbs) - if status.IsSuccess() && len(pods) != 0 { - victims := extenderv1.Victims{ - Pods: pods, - NumPDBViolations: int64(numPDBViolations), - } - c := &candidate{ - victims: &victims, - name: nodeInfoCopy.Node().Name, - } - if numPDBViolations == 0 { - nonViolatingCandidates.add(c) - } else { - violatingCandidates.add(c) - } - nvcSize, vcSize := nonViolatingCandidates.size(), violatingCandidates.size() - if nvcSize > 0 && nvcSize+vcSize >= candidatesNum { - cancel() - } - return - } - if status.IsSuccess() && len(pods) == 0 { - status = framework.AsStatus(fmt.Errorf("expected at least one victim pod on node %q", nodeInfoCopy.Node().Name)) - } - statusesLock.Lock() - if status.Code() == framework.Error { - errs = append(errs, status.AsError()) - } - nodeStatuses.Set(nodeInfoCopy.Node().Name, status) - statusesLock.Unlock() - } - fh.Parallelizer().Until(ctx, len(potentialNodes), checkNode, ev.PluginName) - return append(nonViolatingCandidates.get(), violatingCandidates.get()...), nodeStatuses, utilerrors.NewAggregate(errs) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go deleted file mode 100644 index 77dc23bc5..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/framework.go +++ /dev/null @@ -1,1672 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package runtime - -import ( - "context" - "errors" - "fmt" - "io" - "reflect" - "sort" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/client-go/informers" - clientset "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/events" - "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/klog/v2" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/util/slice" -) - -const ( - // Specifies the maximum timeout a permit plugin can return. - maxTimeout = 15 * time.Minute -) - -// frameworkImpl is the component responsible for initializing and running scheduler -// plugins. -type frameworkImpl struct { - registry Registry - snapshotSharedLister framework.SharedLister - waitingPods *waitingPodsMap - scorePluginWeight map[string]int - preEnqueuePlugins []framework.PreEnqueuePlugin - enqueueExtensions []framework.EnqueueExtensions - queueSortPlugins []framework.QueueSortPlugin - preFilterPlugins []framework.PreFilterPlugin - filterPlugins []framework.FilterPlugin - postFilterPlugins []framework.PostFilterPlugin - preScorePlugins []framework.PreScorePlugin - scorePlugins []framework.ScorePlugin - reservePlugins []framework.ReservePlugin - preBindPlugins []framework.PreBindPlugin - bindPlugins []framework.BindPlugin - postBindPlugins []framework.PostBindPlugin - permitPlugins []framework.PermitPlugin - - // pluginsMap contains all plugins, by name. - pluginsMap map[string]framework.Plugin - - clientSet clientset.Interface - kubeConfig *restclient.Config - eventRecorder events.EventRecorder - informerFactory informers.SharedInformerFactory - sharedDRAManager framework.SharedDRAManager - logger klog.Logger - - metricsRecorder *metrics.MetricAsyncRecorder - profileName string - percentageOfNodesToScore *int32 - - extenders []framework.Extender - framework.PodNominator - framework.PodActivator - - parallelizer parallelize.Parallelizer -} - -// extensionPoint encapsulates desired and applied set of plugins at a specific extension -// point. This is used to simplify iterating over all extension points supported by the -// frameworkImpl. -type extensionPoint struct { - // the set of plugins to be configured at this extension point. - plugins *config.PluginSet - // a pointer to the slice storing plugins implementations that will run at this - // extension point. - slicePtr interface{} -} - -func (f *frameworkImpl) getExtensionPoints(plugins *config.Plugins) []extensionPoint { - return []extensionPoint{ - {&plugins.PreFilter, &f.preFilterPlugins}, - {&plugins.Filter, &f.filterPlugins}, - {&plugins.PostFilter, &f.postFilterPlugins}, - {&plugins.Reserve, &f.reservePlugins}, - {&plugins.PreScore, &f.preScorePlugins}, - {&plugins.Score, &f.scorePlugins}, - {&plugins.PreBind, &f.preBindPlugins}, - {&plugins.Bind, &f.bindPlugins}, - {&plugins.PostBind, &f.postBindPlugins}, - {&plugins.Permit, &f.permitPlugins}, - {&plugins.PreEnqueue, &f.preEnqueuePlugins}, - {&plugins.QueueSort, &f.queueSortPlugins}, - } -} - -// Extenders returns the registered extenders. -func (f *frameworkImpl) Extenders() []framework.Extender { - return f.extenders -} - -type frameworkOptions struct { - componentConfigVersion string - clientSet clientset.Interface - kubeConfig *restclient.Config - eventRecorder events.EventRecorder - informerFactory informers.SharedInformerFactory - sharedDRAManager framework.SharedDRAManager - snapshotSharedLister framework.SharedLister - metricsRecorder *metrics.MetricAsyncRecorder - podNominator framework.PodNominator - podActivator framework.PodActivator - extenders []framework.Extender - captureProfile CaptureProfile - parallelizer parallelize.Parallelizer - waitingPods *waitingPodsMap - logger *klog.Logger -} - -// Option for the frameworkImpl. -type Option func(*frameworkOptions) - -// WithComponentConfigVersion sets the component config version to the -// KubeSchedulerConfiguration version used. The string should be the full -// scheme group/version of the external type we converted from (for example -// "kubescheduler.config.k8s.io/v1") -func WithComponentConfigVersion(componentConfigVersion string) Option { - return func(o *frameworkOptions) { - o.componentConfigVersion = componentConfigVersion - } -} - -// WithClientSet sets clientSet for the scheduling frameworkImpl. -func WithClientSet(clientSet clientset.Interface) Option { - return func(o *frameworkOptions) { - o.clientSet = clientSet - } -} - -// WithKubeConfig sets kubeConfig for the scheduling frameworkImpl. -func WithKubeConfig(kubeConfig *restclient.Config) Option { - return func(o *frameworkOptions) { - o.kubeConfig = kubeConfig - } -} - -// WithEventRecorder sets clientSet for the scheduling frameworkImpl. -func WithEventRecorder(recorder events.EventRecorder) Option { - return func(o *frameworkOptions) { - o.eventRecorder = recorder - } -} - -// WithInformerFactory sets informer factory for the scheduling frameworkImpl. -func WithInformerFactory(informerFactory informers.SharedInformerFactory) Option { - return func(o *frameworkOptions) { - o.informerFactory = informerFactory - } -} - -// WithSharedDRAManager sets SharedDRAManager for the framework. -func WithSharedDRAManager(sharedDRAManager framework.SharedDRAManager) Option { - return func(o *frameworkOptions) { - o.sharedDRAManager = sharedDRAManager - } -} - -// WithSnapshotSharedLister sets the SharedLister of the snapshot. -func WithSnapshotSharedLister(snapshotSharedLister framework.SharedLister) Option { - return func(o *frameworkOptions) { - o.snapshotSharedLister = snapshotSharedLister - } -} - -// WithPodNominator sets podNominator for the scheduling frameworkImpl. -func WithPodNominator(nominator framework.PodNominator) Option { - return func(o *frameworkOptions) { - o.podNominator = nominator - } -} - -func WithPodActivator(activator framework.PodActivator) Option { - return func(o *frameworkOptions) { - o.podActivator = activator - } -} - -// WithExtenders sets extenders for the scheduling frameworkImpl. -func WithExtenders(extenders []framework.Extender) Option { - return func(o *frameworkOptions) { - o.extenders = extenders - } -} - -// WithParallelism sets parallelism for the scheduling frameworkImpl. -func WithParallelism(parallelism int) Option { - return func(o *frameworkOptions) { - o.parallelizer = parallelize.NewParallelizer(parallelism) - } -} - -// CaptureProfile is a callback to capture a finalized profile. -type CaptureProfile func(config.KubeSchedulerProfile) - -// WithCaptureProfile sets a callback to capture the finalized profile. -func WithCaptureProfile(c CaptureProfile) Option { - return func(o *frameworkOptions) { - o.captureProfile = c - } -} - -// WithMetricsRecorder sets metrics recorder for the scheduling frameworkImpl. -func WithMetricsRecorder(r *metrics.MetricAsyncRecorder) Option { - return func(o *frameworkOptions) { - o.metricsRecorder = r - } -} - -// WithWaitingPods sets waitingPods for the scheduling frameworkImpl. -func WithWaitingPods(wp *waitingPodsMap) Option { - return func(o *frameworkOptions) { - o.waitingPods = wp - } -} - -// WithLogger overrides the default logger from k8s.io/klog. -func WithLogger(logger klog.Logger) Option { - return func(o *frameworkOptions) { - o.logger = &logger - } -} - -// defaultFrameworkOptions are applied when no option corresponding to those fields exist. -func defaultFrameworkOptions(stopCh <-chan struct{}) frameworkOptions { - return frameworkOptions{ - metricsRecorder: metrics.NewMetricsAsyncRecorder(1000, time.Second, stopCh), - parallelizer: parallelize.NewParallelizer(parallelize.DefaultParallelism), - } -} - -var _ framework.Framework = &frameworkImpl{} - -// NewFramework initializes plugins given the configuration and the registry. -func NewFramework(ctx context.Context, r Registry, profile *config.KubeSchedulerProfile, opts ...Option) (framework.Framework, error) { - options := defaultFrameworkOptions(ctx.Done()) - for _, opt := range opts { - opt(&options) - } - - logger := klog.FromContext(ctx) - if options.logger != nil { - logger = *options.logger - } - f := &frameworkImpl{ - registry: r, - snapshotSharedLister: options.snapshotSharedLister, - scorePluginWeight: make(map[string]int), - waitingPods: options.waitingPods, - clientSet: options.clientSet, - kubeConfig: options.kubeConfig, - eventRecorder: options.eventRecorder, - informerFactory: options.informerFactory, - sharedDRAManager: options.sharedDRAManager, - metricsRecorder: options.metricsRecorder, - extenders: options.extenders, - PodNominator: options.podNominator, - PodActivator: options.podActivator, - parallelizer: options.parallelizer, - logger: logger, - } - - if len(f.extenders) > 0 { - // Extender doesn't support any kind of requeueing feature like EnqueueExtensions in the scheduling framework. - // We register a defaultEnqueueExtension to framework.ExtenderName here. - // And, in the scheduling cycle, when Extenders reject some Nodes and the pod ends up being unschedulable, - // we put framework.ExtenderName to pInfo.UnschedulablePlugins. - f.enqueueExtensions = []framework.EnqueueExtensions{&defaultEnqueueExtension{pluginName: framework.ExtenderName}} - } - - if profile == nil { - return f, nil - } - - f.profileName = profile.SchedulerName - f.percentageOfNodesToScore = profile.PercentageOfNodesToScore - if profile.Plugins == nil { - return f, nil - } - - // get needed plugins from config - pg := f.pluginsNeeded(profile.Plugins) - - pluginConfig := make(map[string]runtime.Object, len(profile.PluginConfig)) - for i := range profile.PluginConfig { - name := profile.PluginConfig[i].Name - if _, ok := pluginConfig[name]; ok { - return nil, fmt.Errorf("repeated config for plugin %s", name) - } - pluginConfig[name] = profile.PluginConfig[i].Args - } - outputProfile := config.KubeSchedulerProfile{ - SchedulerName: f.profileName, - PercentageOfNodesToScore: f.percentageOfNodesToScore, - Plugins: profile.Plugins, - PluginConfig: make([]config.PluginConfig, 0, len(pg)), - } - - f.pluginsMap = make(map[string]framework.Plugin) - for name, factory := range r { - // initialize only needed plugins. - if !pg.Has(name) { - continue - } - - args := pluginConfig[name] - if args != nil { - outputProfile.PluginConfig = append(outputProfile.PluginConfig, config.PluginConfig{ - Name: name, - Args: args, - }) - } - p, err := factory(ctx, args, f) - if err != nil { - return nil, fmt.Errorf("initializing plugin %q: %w", name, err) - } - f.pluginsMap[name] = p - - f.fillEnqueueExtensions(p) - } - - // initialize plugins per individual extension points - for _, e := range f.getExtensionPoints(profile.Plugins) { - if err := updatePluginList(e.slicePtr, *e.plugins, f.pluginsMap); err != nil { - return nil, err - } - } - - // initialize multiPoint plugins to their expanded extension points - if len(profile.Plugins.MultiPoint.Enabled) > 0 { - if err := f.expandMultiPointPlugins(logger, profile); err != nil { - return nil, err - } - } - - if len(f.queueSortPlugins) != 1 { - return nil, fmt.Errorf("only one queue sort plugin required for profile with scheduler name %q, but got %d", profile.SchedulerName, len(f.queueSortPlugins)) - } - if len(f.bindPlugins) == 0 { - return nil, fmt.Errorf("at least one bind plugin is needed for profile with scheduler name %q", profile.SchedulerName) - } - - if err := getScoreWeights(f, append(profile.Plugins.Score.Enabled, profile.Plugins.MultiPoint.Enabled...)); err != nil { - return nil, err - } - - // Verifying the score weights again since Plugin.Name() could return a different - // value from the one used in the configuration. - for _, scorePlugin := range f.scorePlugins { - if f.scorePluginWeight[scorePlugin.Name()] == 0 { - return nil, fmt.Errorf("score plugin %q is not configured with weight", scorePlugin.Name()) - } - } - - if options.captureProfile != nil { - if len(outputProfile.PluginConfig) != 0 { - sort.Slice(outputProfile.PluginConfig, func(i, j int) bool { - return outputProfile.PluginConfig[i].Name < outputProfile.PluginConfig[j].Name - }) - } else { - outputProfile.PluginConfig = nil - } - options.captureProfile(outputProfile) - } - - // Logs Enabled Plugins at each extension point, taking default plugins, given config, and multipoint into consideration - logger.V(2).Info("the scheduler starts to work with those plugins", "Plugins", *f.ListPlugins()) - f.setInstrumentedPlugins() - return f, nil -} - -// setInstrumentedPlugins initializes instrumented plugins from current plugins that frameworkImpl has. -func (f *frameworkImpl) setInstrumentedPlugins() { - // Cache metric streams for prefilter and filter plugins. - for i, pl := range f.preFilterPlugins { - f.preFilterPlugins[i] = &instrumentedPreFilterPlugin{ - PreFilterPlugin: f.preFilterPlugins[i], - metric: metrics.PluginEvaluationTotal.WithLabelValues(pl.Name(), metrics.PreFilter, f.profileName), - } - } - for i, pl := range f.filterPlugins { - f.filterPlugins[i] = &instrumentedFilterPlugin{ - FilterPlugin: f.filterPlugins[i], - metric: metrics.PluginEvaluationTotal.WithLabelValues(pl.Name(), metrics.Filter, f.profileName), - } - } - - // Cache metric streams for prescore and score plugins. - for i, pl := range f.preScorePlugins { - f.preScorePlugins[i] = &instrumentedPreScorePlugin{ - PreScorePlugin: f.preScorePlugins[i], - metric: metrics.PluginEvaluationTotal.WithLabelValues(pl.Name(), metrics.PreScore, f.profileName), - } - } - for i, pl := range f.scorePlugins { - f.scorePlugins[i] = &instrumentedScorePlugin{ - ScorePlugin: f.scorePlugins[i], - metric: metrics.PluginEvaluationTotal.WithLabelValues(pl.Name(), metrics.Score, f.profileName), - } - } -} - -func (f *frameworkImpl) SetPodNominator(n framework.PodNominator) { - f.PodNominator = n -} - -func (f *frameworkImpl) SetPodActivator(a framework.PodActivator) { - f.PodActivator = a -} - -// Close closes each plugin, when they implement io.Closer interface. -func (f *frameworkImpl) Close() error { - var errs []error - for name, plugin := range f.pluginsMap { - if closer, ok := plugin.(io.Closer); ok { - err := closer.Close() - if err != nil { - errs = append(errs, fmt.Errorf("%s failed to close: %w", name, err)) - // We try to close all plugins even if we got errors from some. - } - } - } - return errors.Join(errs...) -} - -// getScoreWeights makes sure that, between MultiPoint-Score plugin weights and individual Score -// plugin weights there is not an overflow of MaxTotalScore. -func getScoreWeights(f *frameworkImpl, plugins []config.Plugin) error { - var totalPriority int64 - scorePlugins := reflect.ValueOf(&f.scorePlugins).Elem() - pluginType := scorePlugins.Type().Elem() - for _, e := range plugins { - pg := f.pluginsMap[e.Name] - if !reflect.TypeOf(pg).Implements(pluginType) { - continue - } - - // We append MultiPoint plugins to the list of Score plugins. So if this plugin has already been - // encountered, let the individual Score weight take precedence. - if _, ok := f.scorePluginWeight[e.Name]; ok { - continue - } - // a weight of zero is not permitted, plugins can be disabled explicitly - // when configured. - f.scorePluginWeight[e.Name] = int(e.Weight) - if f.scorePluginWeight[e.Name] == 0 { - f.scorePluginWeight[e.Name] = 1 - } - - // Checks totalPriority against MaxTotalScore to avoid overflow - if int64(f.scorePluginWeight[e.Name])*framework.MaxNodeScore > framework.MaxTotalScore-totalPriority { - return fmt.Errorf("total score of Score plugins could overflow") - } - totalPriority += int64(f.scorePluginWeight[e.Name]) * framework.MaxNodeScore - } - return nil -} - -type orderedSet struct { - set map[string]int - list []string - deletionCnt int -} - -func newOrderedSet() *orderedSet { - return &orderedSet{set: make(map[string]int)} -} - -func (os *orderedSet) insert(s string) { - if os.has(s) { - return - } - os.set[s] = len(os.list) - os.list = append(os.list, s) -} - -func (os *orderedSet) has(s string) bool { - _, found := os.set[s] - return found -} - -func (os *orderedSet) delete(s string) { - if i, found := os.set[s]; found { - delete(os.set, s) - os.list = append(os.list[:i-os.deletionCnt], os.list[i+1-os.deletionCnt:]...) - os.deletionCnt++ - } -} - -func (f *frameworkImpl) expandMultiPointPlugins(logger klog.Logger, profile *config.KubeSchedulerProfile) error { - // initialize MultiPoint plugins - for _, e := range f.getExtensionPoints(profile.Plugins) { - plugins := reflect.ValueOf(e.slicePtr).Elem() - pluginType := plugins.Type().Elem() - // build enabledSet of plugins already registered via normal extension points - // to check double registration - enabledSet := newOrderedSet() - for _, plugin := range e.plugins.Enabled { - enabledSet.insert(plugin.Name) - } - - disabledSet := sets.New[string]() - for _, disabledPlugin := range e.plugins.Disabled { - disabledSet.Insert(disabledPlugin.Name) - } - if disabledSet.Has("*") { - logger.V(4).Info("Skipped MultiPoint expansion because all plugins are disabled for extension point", "extension", pluginType) - continue - } - - // track plugins enabled via multipoint separately from those enabled by specific extensions, - // so that we can distinguish between double-registration and explicit overrides - multiPointEnabled := newOrderedSet() - overridePlugins := newOrderedSet() - for _, ep := range profile.Plugins.MultiPoint.Enabled { - pg, ok := f.pluginsMap[ep.Name] - if !ok { - return fmt.Errorf("%s %q does not exist", pluginType.Name(), ep.Name) - } - - // if this plugin doesn't implement the type for the current extension we're trying to expand, skip - if !reflect.TypeOf(pg).Implements(pluginType) { - continue - } - - // a plugin that's enabled via MultiPoint can still be disabled for specific extension points - if disabledSet.Has(ep.Name) { - logger.V(4).Info("Skipped disabled plugin for extension point", "plugin", ep.Name, "extension", pluginType) - continue - } - - // if this plugin has already been enabled by the specific extension point, - // the user intent is to override the default plugin or make some other explicit setting. - // Either way, discard the MultiPoint value for this plugin. - // This maintains expected behavior for overriding default plugins (see https://github.com/kubernetes/kubernetes/pull/99582) - if enabledSet.has(ep.Name) { - overridePlugins.insert(ep.Name) - logger.Info("MultiPoint plugin is explicitly re-configured; overriding", "plugin", ep.Name) - continue - } - - // if this plugin is already registered via MultiPoint, then this is - // a double registration and an error in the config. - if multiPointEnabled.has(ep.Name) { - return fmt.Errorf("plugin %q already registered as %q", ep.Name, pluginType.Name()) - } - - // we only need to update the multipoint set, since we already have the specific extension set from above - multiPointEnabled.insert(ep.Name) - } - - // Reorder plugins. Here is the expected order: - // - part 1: overridePlugins. Their order stay intact as how they're specified in regular extension point. - // - part 2: multiPointEnabled - i.e., plugin defined in multipoint but not in regular extension point. - // - part 3: other plugins (excluded by part 1 & 2) in regular extension point. - newPlugins := reflect.New(reflect.TypeOf(e.slicePtr).Elem()).Elem() - // part 1 - for _, name := range slice.CopyStrings(enabledSet.list) { - if overridePlugins.has(name) { - newPlugins = reflect.Append(newPlugins, reflect.ValueOf(f.pluginsMap[name])) - enabledSet.delete(name) - } - } - // part 2 - for _, name := range multiPointEnabled.list { - newPlugins = reflect.Append(newPlugins, reflect.ValueOf(f.pluginsMap[name])) - } - // part 3 - for _, name := range enabledSet.list { - newPlugins = reflect.Append(newPlugins, reflect.ValueOf(f.pluginsMap[name])) - } - plugins.Set(newPlugins) - } - return nil -} - -func shouldHaveEnqueueExtensions(p framework.Plugin) bool { - switch p.(type) { - // Only PreEnqueue, PreFilter, Filter, Reserve, and Permit plugins can (should) have EnqueueExtensions. - // See the comment of EnqueueExtensions for more detailed reason here. - case framework.PreEnqueuePlugin, framework.PreFilterPlugin, framework.FilterPlugin, framework.ReservePlugin, framework.PermitPlugin: - return true - } - return false -} - -func (f *frameworkImpl) fillEnqueueExtensions(p framework.Plugin) { - if !shouldHaveEnqueueExtensions(p) { - // Ignore EnqueueExtensions from plugin which isn't PreEnqueue, PreFilter, Filter, Reserve, and Permit. - return - } - - ext, ok := p.(framework.EnqueueExtensions) - if !ok { - // If interface EnqueueExtensions is not implemented, register the default enqueue extensions - // to the plugin because we don't know which events the plugin is interested in. - // This is to ensure backward compatibility. - f.enqueueExtensions = append(f.enqueueExtensions, &defaultEnqueueExtension{pluginName: p.Name()}) - return - } - - f.enqueueExtensions = append(f.enqueueExtensions, ext) -} - -// defaultEnqueueExtension is used when a plugin does not implement EnqueueExtensions interface. -type defaultEnqueueExtension struct { - pluginName string -} - -func (p *defaultEnqueueExtension) Name() string { return p.pluginName } -func (p *defaultEnqueueExtension) EventsToRegister(_ context.Context) ([]framework.ClusterEventWithHint, error) { - // need to return all specific cluster events with framework.All action instead of wildcard event - // because the returning values are used to register event handlers. - // If we return the wildcard here, it won't affect the event handlers registered by the plugin - // and some events may not be registered in the event handlers. - return framework.UnrollWildCardResource(), nil -} - -func updatePluginList(pluginList interface{}, pluginSet config.PluginSet, pluginsMap map[string]framework.Plugin) error { - plugins := reflect.ValueOf(pluginList).Elem() - pluginType := plugins.Type().Elem() - set := sets.New[string]() - for _, ep := range pluginSet.Enabled { - pg, ok := pluginsMap[ep.Name] - if !ok { - return fmt.Errorf("%s %q does not exist", pluginType.Name(), ep.Name) - } - - if !reflect.TypeOf(pg).Implements(pluginType) { - return fmt.Errorf("plugin %q does not extend %s plugin", ep.Name, pluginType.Name()) - } - - if set.Has(ep.Name) { - return fmt.Errorf("plugin %q already registered as %q", ep.Name, pluginType.Name()) - } - - set.Insert(ep.Name) - - newPlugins := reflect.Append(plugins, reflect.ValueOf(pg)) - plugins.Set(newPlugins) - } - return nil -} - -// PreEnqueuePlugins returns the registered preEnqueue plugins. -func (f *frameworkImpl) PreEnqueuePlugins() []framework.PreEnqueuePlugin { - return f.preEnqueuePlugins -} - -// EnqueueExtensions returns the registered reenqueue plugins. -func (f *frameworkImpl) EnqueueExtensions() []framework.EnqueueExtensions { - return f.enqueueExtensions -} - -// QueueSortFunc returns the function to sort pods in scheduling queue -func (f *frameworkImpl) QueueSortFunc() framework.LessFunc { - if f == nil { - // If frameworkImpl is nil, simply keep their order unchanged. - // NOTE: this is primarily for tests. - return func(_, _ *framework.QueuedPodInfo) bool { return false } - } - - if len(f.queueSortPlugins) == 0 { - panic("No QueueSort plugin is registered in the frameworkImpl.") - } - - // Only one QueueSort plugin can be enabled. - return f.queueSortPlugins[0].Less -} - -// RunPreFilterPlugins runs the set of configured PreFilter plugins. It returns -// *Status and its code is set to non-success if any of the plugins returns -// anything but Success/Skip. -// When it returns Skip status, returned PreFilterResult and other fields in status are just ignored, -// and coupled Filter plugin/PreFilterExtensions() will be skipped in this scheduling cycle. -// If a non-success status is returned, then the scheduling cycle is aborted. -func (f *frameworkImpl) RunPreFilterPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod) (_ *framework.PreFilterResult, status *framework.Status, _ sets.Set[string]) { - startTime := time.Now() - skipPlugins := sets.New[string]() - defer func() { - state.SkipFilterPlugins = skipPlugins - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PreFilter, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - var result *framework.PreFilterResult - pluginsWithNodes := sets.New[string]() - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "PreFilter") - } - var returnStatus *framework.Status - for _, pl := range f.preFilterPlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - r, s := f.runPreFilterPlugin(ctx, pl, state, pod) - if s.IsSkip() { - skipPlugins.Insert(pl.Name()) - continue - } - if !s.IsSuccess() { - s.SetPlugin(pl.Name()) - if s.Code() == framework.UnschedulableAndUnresolvable { - // In this case, the preemption shouldn't happen in this scheduling cycle. - // So, no need to execute all PreFilter. - return nil, s, nil - } - if s.Code() == framework.Unschedulable { - // In this case, the preemption should happen later in this scheduling cycle. - // So we need to execute all PreFilter. - // https://github.com/kubernetes/kubernetes/issues/119770 - returnStatus = s - continue - } - return nil, framework.AsStatus(fmt.Errorf("running PreFilter plugin %q: %w", pl.Name(), s.AsError())).WithPlugin(pl.Name()), nil - } - if !r.AllNodes() { - pluginsWithNodes.Insert(pl.Name()) - } - result = result.Merge(r) - if !result.AllNodes() && len(result.NodeNames) == 0 { - msg := fmt.Sprintf("node(s) didn't satisfy plugin(s) %v simultaneously", sets.List(pluginsWithNodes)) - if len(pluginsWithNodes) == 1 { - msg = fmt.Sprintf("node(s) didn't satisfy plugin %v", sets.List(pluginsWithNodes)[0]) - } - - // When PreFilterResult filters out Nodes, the framework considers Nodes that are filtered out as getting "UnschedulableAndUnresolvable". - return result, framework.NewStatus(framework.UnschedulableAndUnresolvable, msg), pluginsWithNodes - } - } - return result, returnStatus, pluginsWithNodes -} - -func (f *frameworkImpl) runPreFilterPlugin(ctx context.Context, pl framework.PreFilterPlugin, state *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - if !state.ShouldRecordPluginMetrics() { - return pl.PreFilter(ctx, state, pod) - } - startTime := time.Now() - result, status := pl.PreFilter(ctx, state, pod) - f.metricsRecorder.ObservePluginDurationAsync(metrics.PreFilter, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return result, status -} - -// RunPreFilterExtensionAddPod calls the AddPod interface for the set of configured -// PreFilter plugins. It returns directly if any of the plugins return any -// status other than Success. -func (f *frameworkImpl) RunPreFilterExtensionAddPod( - ctx context.Context, - state *framework.CycleState, - podToSchedule *v1.Pod, - podInfoToAdd *framework.PodInfo, - nodeInfo *framework.NodeInfo, -) (status *framework.Status) { - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "PreFilterExtension") - } - for _, pl := range f.preFilterPlugins { - if pl.PreFilterExtensions() == nil || state.SkipFilterPlugins.Has(pl.Name()) { - continue - } - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - status = f.runPreFilterExtensionAddPod(ctx, pl, state, podToSchedule, podInfoToAdd, nodeInfo) - if !status.IsSuccess() { - err := status.AsError() - logger.Error(err, "Plugin failed", "pod", klog.KObj(podToSchedule), "node", klog.KObj(nodeInfo.Node()), "operation", "addPod", "plugin", pl.Name()) - return framework.AsStatus(fmt.Errorf("running AddPod on PreFilter plugin %q: %w", pl.Name(), err)) - } - } - - return nil -} - -func (f *frameworkImpl) runPreFilterExtensionAddPod(ctx context.Context, pl framework.PreFilterPlugin, state *framework.CycleState, podToSchedule *v1.Pod, podInfoToAdd *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return pl.PreFilterExtensions().AddPod(ctx, state, podToSchedule, podInfoToAdd, nodeInfo) - } - startTime := time.Now() - status := pl.PreFilterExtensions().AddPod(ctx, state, podToSchedule, podInfoToAdd, nodeInfo) - f.metricsRecorder.ObservePluginDurationAsync(metrics.PreFilterExtensionAddPod, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunPreFilterExtensionRemovePod calls the RemovePod interface for the set of configured -// PreFilter plugins. It returns directly if any of the plugins return any -// status other than Success. -func (f *frameworkImpl) RunPreFilterExtensionRemovePod( - ctx context.Context, - state *framework.CycleState, - podToSchedule *v1.Pod, - podInfoToRemove *framework.PodInfo, - nodeInfo *framework.NodeInfo, -) (status *framework.Status) { - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "PreFilterExtension") - } - for _, pl := range f.preFilterPlugins { - if pl.PreFilterExtensions() == nil || state.SkipFilterPlugins.Has(pl.Name()) { - continue - } - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - status = f.runPreFilterExtensionRemovePod(ctx, pl, state, podToSchedule, podInfoToRemove, nodeInfo) - if !status.IsSuccess() { - err := status.AsError() - logger.Error(err, "Plugin failed", "node", klog.KObj(nodeInfo.Node()), "operation", "removePod", "plugin", pl.Name(), "pod", klog.KObj(podToSchedule)) - return framework.AsStatus(fmt.Errorf("running RemovePod on PreFilter plugin %q: %w", pl.Name(), err)) - } - } - - return nil -} - -func (f *frameworkImpl) runPreFilterExtensionRemovePod(ctx context.Context, pl framework.PreFilterPlugin, state *framework.CycleState, podToSchedule *v1.Pod, podInfoToRemove *framework.PodInfo, nodeInfo *framework.NodeInfo) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return pl.PreFilterExtensions().RemovePod(ctx, state, podToSchedule, podInfoToRemove, nodeInfo) - } - startTime := time.Now() - status := pl.PreFilterExtensions().RemovePod(ctx, state, podToSchedule, podInfoToRemove, nodeInfo) - f.metricsRecorder.ObservePluginDurationAsync(metrics.PreFilterExtensionRemovePod, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunFilterPlugins runs the set of configured Filter plugins for pod on -// the given node. If any of these plugins doesn't return "Success", the -// given node is not suitable for running pod. -// Meanwhile, the failure message and status are set for the given node. -func (f *frameworkImpl) RunFilterPlugins( - ctx context.Context, - state *framework.CycleState, - pod *v1.Pod, - nodeInfo *framework.NodeInfo, -) *framework.Status { - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "Filter") - } - - for _, pl := range f.filterPlugins { - if state.SkipFilterPlugins.Has(pl.Name()) { - continue - } - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - if status := f.runFilterPlugin(ctx, pl, state, pod, nodeInfo); !status.IsSuccess() { - if !status.IsRejected() { - // Filter plugins are not supposed to return any status other than - // Success or Unschedulable. - status = framework.AsStatus(fmt.Errorf("running %q filter plugin: %w", pl.Name(), status.AsError())) - } - status.SetPlugin(pl.Name()) - return status - } - } - - return nil -} - -func (f *frameworkImpl) runFilterPlugin(ctx context.Context, pl framework.FilterPlugin, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return pl.Filter(ctx, state, pod, nodeInfo) - } - startTime := time.Now() - status := pl.Filter(ctx, state, pod, nodeInfo) - f.metricsRecorder.ObservePluginDurationAsync(metrics.Filter, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunPostFilterPlugins runs the set of configured PostFilter plugins until the first -// Success, Error or UnschedulableAndUnresolvable is met; otherwise continues to execute all plugins. -func (f *frameworkImpl) RunPostFilterPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod, filteredNodeStatusMap framework.NodeToStatusReader) (_ *framework.PostFilterResult, status *framework.Status) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PostFilter, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "PostFilter") - } - - // `result` records the last meaningful(non-noop) PostFilterResult. - var result *framework.PostFilterResult - var reasons []string - var rejectorPlugin string - for _, pl := range f.postFilterPlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - r, s := f.runPostFilterPlugin(ctx, pl, state, pod, filteredNodeStatusMap) - if s.IsSuccess() { - return r, s - } else if s.Code() == framework.UnschedulableAndUnresolvable { - return r, s.WithPlugin(pl.Name()) - } else if !s.IsRejected() { - // Any status other than Success, Unschedulable or UnschedulableAndUnresolvable is Error. - return nil, framework.AsStatus(s.AsError()).WithPlugin(pl.Name()) - } else if r != nil && r.Mode() != framework.ModeNoop { - result = r - } - - reasons = append(reasons, s.Reasons()...) - // Record the first failed plugin unless we proved that - // the latter is more relevant. - if len(rejectorPlugin) == 0 { - rejectorPlugin = pl.Name() - } - } - - return result, framework.NewStatus(framework.Unschedulable, reasons...).WithPlugin(rejectorPlugin) -} - -func (f *frameworkImpl) runPostFilterPlugin(ctx context.Context, pl framework.PostFilterPlugin, state *framework.CycleState, pod *v1.Pod, filteredNodeStatusMap framework.NodeToStatusReader) (*framework.PostFilterResult, *framework.Status) { - if !state.ShouldRecordPluginMetrics() { - return pl.PostFilter(ctx, state, pod, filteredNodeStatusMap) - } - startTime := time.Now() - r, s := pl.PostFilter(ctx, state, pod, filteredNodeStatusMap) - f.metricsRecorder.ObservePluginDurationAsync(metrics.PostFilter, pl.Name(), s.Code().String(), metrics.SinceInSeconds(startTime)) - return r, s -} - -// RunFilterPluginsWithNominatedPods runs the set of configured filter plugins -// for nominated pod on the given node. -// This function is called from two different places: Schedule and Preempt. -// When it is called from Schedule, we want to test whether the pod is -// schedulable on the node with all the existing pods on the node plus higher -// and equal priority pods nominated to run on the node. -// When it is called from Preempt, we should remove the victims of preemption -// and add the nominated pods. Removal of the victims is done by -// SelectVictimsOnNode(). Preempt removes victims from PreFilter state and -// NodeInfo before calling this function. -func (f *frameworkImpl) RunFilterPluginsWithNominatedPods(ctx context.Context, state *framework.CycleState, pod *v1.Pod, info *framework.NodeInfo) *framework.Status { - var status *framework.Status - - podsAdded := false - // We run filters twice in some cases. If the node has greater or equal priority - // nominated pods, we run them when those pods are added to PreFilter state and nodeInfo. - // If all filters succeed in this pass, we run them again when these - // nominated pods are not added. This second pass is necessary because some - // filters such as inter-pod affinity may not pass without the nominated pods. - // If there are no nominated pods for the node or if the first run of the - // filters fail, we don't run the second pass. - // We consider only equal or higher priority pods in the first pass, because - // those are the current "pod" must yield to them and not take a space opened - // for running them. It is ok if the current "pod" take resources freed for - // lower priority pods. - // Requiring that the new pod is schedulable in both circumstances ensures that - // we are making a conservative decision: filters like resources and inter-pod - // anti-affinity are more likely to fail when the nominated pods are treated - // as running, while filters like pod affinity are more likely to fail when - // the nominated pods are treated as not running. We can't just assume the - // nominated pods are running because they are not running right now and in fact, - // they may end up getting scheduled to a different node. - logger := klog.FromContext(ctx) - logger = klog.LoggerWithName(logger, "FilterWithNominatedPods") - ctx = klog.NewContext(ctx, logger) - for i := 0; i < 2; i++ { - stateToUse := state - nodeInfoToUse := info - if i == 0 { - var err error - podsAdded, stateToUse, nodeInfoToUse, err = addGENominatedPods(ctx, f, pod, state, info) - if err != nil { - return framework.AsStatus(err) - } - } else if !podsAdded || !status.IsSuccess() { - break - } - - status = f.RunFilterPlugins(ctx, stateToUse, pod, nodeInfoToUse) - if !status.IsSuccess() && !status.IsRejected() { - return status - } - } - - return status -} - -// addGENominatedPods adds pods with equal or greater priority which are nominated -// to run on the node. It returns 1) whether any pod was added, 2) augmented cycleState, -// 3) augmented nodeInfo. -func addGENominatedPods(ctx context.Context, fh framework.Handle, pod *v1.Pod, state *framework.CycleState, nodeInfo *framework.NodeInfo) (bool, *framework.CycleState, *framework.NodeInfo, error) { - if fh == nil { - // This may happen only in tests. - return false, state, nodeInfo, nil - } - nominatedPodInfos := fh.NominatedPodsForNode(nodeInfo.Node().Name) - if len(nominatedPodInfos) == 0 { - return false, state, nodeInfo, nil - } - nodeInfoOut := nodeInfo.Snapshot() - stateOut := state.Clone() - podsAdded := false - for _, pi := range nominatedPodInfos { - if corev1.PodPriority(pi.Pod) >= corev1.PodPriority(pod) && pi.Pod.UID != pod.UID { - nodeInfoOut.AddPodInfo(pi) - status := fh.RunPreFilterExtensionAddPod(ctx, stateOut, pod, pi, nodeInfoOut) - if !status.IsSuccess() { - return false, state, nodeInfo, status.AsError() - } - podsAdded = true - } - } - return podsAdded, stateOut, nodeInfoOut, nil -} - -// RunPreScorePlugins runs the set of configured pre-score plugins. If any -// of these plugins returns any status other than Success/Skip, the given pod is rejected. -// When it returns Skip status, other fields in status are just ignored, -// and coupled Score plugin will be skipped in this scheduling cycle. -func (f *frameworkImpl) RunPreScorePlugins( - ctx context.Context, - state *framework.CycleState, - pod *v1.Pod, - nodes []*framework.NodeInfo, -) (status *framework.Status) { - startTime := time.Now() - skipPlugins := sets.New[string]() - defer func() { - state.SkipScorePlugins = skipPlugins - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PreScore, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "PreScore") - } - for _, pl := range f.preScorePlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - status = f.runPreScorePlugin(ctx, pl, state, pod, nodes) - if status.IsSkip() { - skipPlugins.Insert(pl.Name()) - continue - } - if !status.IsSuccess() { - return framework.AsStatus(fmt.Errorf("running PreScore plugin %q: %w", pl.Name(), status.AsError())) - } - } - return nil -} - -func (f *frameworkImpl) runPreScorePlugin(ctx context.Context, pl framework.PreScorePlugin, state *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return pl.PreScore(ctx, state, pod, nodes) - } - startTime := time.Now() - status := pl.PreScore(ctx, state, pod, nodes) - f.metricsRecorder.ObservePluginDurationAsync(metrics.PreScore, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunScorePlugins runs the set of configured scoring plugins. -// It returns a list that stores scores from each plugin and total score for each Node. -// It also returns *Status, which is set to non-success if any of the plugins returns -// a non-success status. -func (f *frameworkImpl) RunScorePlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) (ns []framework.NodePluginScores, status *framework.Status) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Score, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - allNodePluginScores := make([]framework.NodePluginScores, len(nodes)) - numPlugins := len(f.scorePlugins) - plugins := make([]framework.ScorePlugin, 0, numPlugins) - pluginToNodeScores := make(map[string]framework.NodeScoreList, numPlugins) - for _, pl := range f.scorePlugins { - if state.SkipScorePlugins.Has(pl.Name()) { - continue - } - plugins = append(plugins, pl) - pluginToNodeScores[pl.Name()] = make(framework.NodeScoreList, len(nodes)) - } - ctx, cancel := context.WithCancel(ctx) - defer cancel() - errCh := parallelize.NewErrorChannel() - - if len(plugins) > 0 { - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "Score") - } - // Run Score method for each node in parallel. - f.Parallelizer().Until(ctx, len(nodes), func(index int) { - nodeInfo := nodes[index] - nodeName := nodeInfo.Node().Name - logger := logger - if verboseLogs { - logger = klog.LoggerWithValues(logger, "node", klog.ObjectRef{Name: nodeName}) - } - for _, pl := range plugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - s, status := f.runScorePlugin(ctx, pl, state, pod, nodeInfo) - if !status.IsSuccess() { - err := fmt.Errorf("plugin %q failed with: %w", pl.Name(), status.AsError()) - errCh.SendErrorWithCancel(err, cancel) - return - } - pluginToNodeScores[pl.Name()][index] = framework.NodeScore{ - Name: nodeName, - Score: s, - } - } - }, metrics.Score) - if err := errCh.ReceiveError(); err != nil { - return nil, framework.AsStatus(fmt.Errorf("running Score plugins: %w", err)) - } - } - - // Run NormalizeScore method for each ScorePlugin in parallel. - f.Parallelizer().Until(ctx, len(plugins), func(index int) { - pl := plugins[index] - if pl.ScoreExtensions() == nil { - return - } - nodeScoreList := pluginToNodeScores[pl.Name()] - status := f.runScoreExtension(ctx, pl, state, pod, nodeScoreList) - if !status.IsSuccess() { - err := fmt.Errorf("plugin %q failed with: %w", pl.Name(), status.AsError()) - errCh.SendErrorWithCancel(err, cancel) - return - } - }, metrics.Score) - if err := errCh.ReceiveError(); err != nil { - return nil, framework.AsStatus(fmt.Errorf("running Normalize on Score plugins: %w", err)) - } - - // Apply score weight for each ScorePlugin in parallel, - // and then, build allNodePluginScores. - f.Parallelizer().Until(ctx, len(nodes), func(index int) { - nodePluginScores := framework.NodePluginScores{ - Name: nodes[index].Node().Name, - Scores: make([]framework.PluginScore, len(plugins)), - } - - for i, pl := range plugins { - weight := f.scorePluginWeight[pl.Name()] - nodeScoreList := pluginToNodeScores[pl.Name()] - score := nodeScoreList[index].Score - - if score > framework.MaxNodeScore || score < framework.MinNodeScore { - err := fmt.Errorf("plugin %q returns an invalid score %v, it should in the range of [%v, %v] after normalizing", pl.Name(), score, framework.MinNodeScore, framework.MaxNodeScore) - errCh.SendErrorWithCancel(err, cancel) - return - } - weightedScore := score * int64(weight) - nodePluginScores.Scores[i] = framework.PluginScore{ - Name: pl.Name(), - Score: weightedScore, - } - nodePluginScores.TotalScore += weightedScore - } - allNodePluginScores[index] = nodePluginScores - }, metrics.Score) - if err := errCh.ReceiveError(); err != nil { - return nil, framework.AsStatus(fmt.Errorf("applying score defaultWeights on Score plugins: %w", err)) - } - - return allNodePluginScores, nil -} - -func (f *frameworkImpl) runScorePlugin(ctx context.Context, pl framework.ScorePlugin, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - if !state.ShouldRecordPluginMetrics() { - return pl.Score(ctx, state, pod, nodeInfo) - } - startTime := time.Now() - s, status := pl.Score(ctx, state, pod, nodeInfo) - f.metricsRecorder.ObservePluginDurationAsync(metrics.Score, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return s, status -} - -func (f *frameworkImpl) runScoreExtension(ctx context.Context, pl framework.ScorePlugin, state *framework.CycleState, pod *v1.Pod, nodeScoreList framework.NodeScoreList) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return pl.ScoreExtensions().NormalizeScore(ctx, state, pod, nodeScoreList) - } - startTime := time.Now() - status := pl.ScoreExtensions().NormalizeScore(ctx, state, pod, nodeScoreList) - f.metricsRecorder.ObservePluginDurationAsync(metrics.ScoreExtensionNormalize, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunPreBindPlugins runs the set of configured prebind plugins. It returns a -// failure (bool) if any of the plugins returns an error. It also returns an -// error containing the rejection message or the error occurred in the plugin. -func (f *frameworkImpl) RunPreBindPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (status *framework.Status) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PreBind, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "PreBind") - logger = klog.LoggerWithValues(logger, "node", klog.ObjectRef{Name: nodeName}) - } - for _, pl := range f.preBindPlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - status = f.runPreBindPlugin(ctx, pl, state, pod, nodeName) - if !status.IsSuccess() { - if status.IsRejected() { - logger.V(4).Info("Pod rejected by PreBind plugin", "pod", klog.KObj(pod), "node", nodeName, "plugin", pl.Name(), "status", status.Message()) - status.SetPlugin(pl.Name()) - return status - } - err := status.AsError() - logger.Error(err, "Plugin failed", "plugin", pl.Name(), "pod", klog.KObj(pod), "node", nodeName) - return framework.AsStatus(fmt.Errorf("running PreBind plugin %q: %w", pl.Name(), err)) - } - } - return nil -} - -func (f *frameworkImpl) runPreBindPlugin(ctx context.Context, pl framework.PreBindPlugin, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return pl.PreBind(ctx, state, pod, nodeName) - } - startTime := time.Now() - status := pl.PreBind(ctx, state, pod, nodeName) - f.metricsRecorder.ObservePluginDurationAsync(metrics.PreBind, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunBindPlugins runs the set of configured bind plugins until one returns a non `Skip` status. -func (f *frameworkImpl) RunBindPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (status *framework.Status) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Bind, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - if len(f.bindPlugins) == 0 { - return framework.NewStatus(framework.Skip, "") - } - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "Bind") - } - for _, pl := range f.bindPlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - status = f.runBindPlugin(ctx, pl, state, pod, nodeName) - if status.IsSkip() { - continue - } - if !status.IsSuccess() { - if status.IsRejected() { - logger.V(4).Info("Pod rejected by Bind plugin", "pod", klog.KObj(pod), "node", nodeName, "plugin", pl.Name(), "status", status.Message()) - status.SetPlugin(pl.Name()) - return status - } - err := status.AsError() - logger.Error(err, "Plugin Failed", "plugin", pl.Name(), "pod", klog.KObj(pod), "node", nodeName) - return framework.AsStatus(fmt.Errorf("running Bind plugin %q: %w", pl.Name(), err)) - } - return status - } - return status -} - -func (f *frameworkImpl) runBindPlugin(ctx context.Context, bp framework.BindPlugin, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return bp.Bind(ctx, state, pod, nodeName) - } - startTime := time.Now() - status := bp.Bind(ctx, state, pod, nodeName) - f.metricsRecorder.ObservePluginDurationAsync(metrics.Bind, bp.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunPostBindPlugins runs the set of configured postbind plugins. -func (f *frameworkImpl) RunPostBindPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.PostBind, framework.Success.String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "PostBind") - } - for _, pl := range f.postBindPlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - f.runPostBindPlugin(ctx, pl, state, pod, nodeName) - } -} - -func (f *frameworkImpl) runPostBindPlugin(ctx context.Context, pl framework.PostBindPlugin, state *framework.CycleState, pod *v1.Pod, nodeName string) { - if !state.ShouldRecordPluginMetrics() { - pl.PostBind(ctx, state, pod, nodeName) - return - } - startTime := time.Now() - pl.PostBind(ctx, state, pod, nodeName) - f.metricsRecorder.ObservePluginDurationAsync(metrics.PostBind, pl.Name(), framework.Success.String(), metrics.SinceInSeconds(startTime)) -} - -// RunReservePluginsReserve runs the Reserve method in the set of configured -// reserve plugins. If any of these plugins returns an error, it does not -// continue running the remaining ones and returns the error. In such a case, -// the pod will not be scheduled and the caller will be expected to call -// RunReservePluginsUnreserve. -func (f *frameworkImpl) RunReservePluginsReserve(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (status *framework.Status) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Reserve, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "Reserve") - logger = klog.LoggerWithValues(logger, "node", klog.ObjectRef{Name: nodeName}) - } - for _, pl := range f.reservePlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - status = f.runReservePluginReserve(ctx, pl, state, pod, nodeName) - if !status.IsSuccess() { - if status.IsRejected() { - logger.V(4).Info("Pod rejected by plugin", "pod", klog.KObj(pod), "plugin", pl.Name(), "status", status.Message()) - status.SetPlugin(pl.Name()) - return status - } - err := status.AsError() - logger.Error(err, "Plugin failed", "plugin", pl.Name(), "pod", klog.KObj(pod)) - return framework.AsStatus(fmt.Errorf("running Reserve plugin %q: %w", pl.Name(), err)) - } - } - return nil -} - -func (f *frameworkImpl) runReservePluginReserve(ctx context.Context, pl framework.ReservePlugin, state *framework.CycleState, pod *v1.Pod, nodeName string) *framework.Status { - if !state.ShouldRecordPluginMetrics() { - return pl.Reserve(ctx, state, pod, nodeName) - } - startTime := time.Now() - status := pl.Reserve(ctx, state, pod, nodeName) - f.metricsRecorder.ObservePluginDurationAsync(metrics.Reserve, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status -} - -// RunReservePluginsUnreserve runs the Unreserve method in the set of -// configured reserve plugins. -func (f *frameworkImpl) RunReservePluginsUnreserve(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Unreserve, framework.Success.String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - // Execute the Unreserve operation of each reserve plugin in the - // *reverse* order in which the Reserve operation was executed. - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "Unreserve") - logger = klog.LoggerWithValues(logger, "node", klog.ObjectRef{Name: nodeName}) - } - for i := len(f.reservePlugins) - 1; i >= 0; i-- { - pl := f.reservePlugins[i] - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - f.runReservePluginUnreserve(ctx, pl, state, pod, nodeName) - } -} - -func (f *frameworkImpl) runReservePluginUnreserve(ctx context.Context, pl framework.ReservePlugin, state *framework.CycleState, pod *v1.Pod, nodeName string) { - if !state.ShouldRecordPluginMetrics() { - pl.Unreserve(ctx, state, pod, nodeName) - return - } - startTime := time.Now() - pl.Unreserve(ctx, state, pod, nodeName) - f.metricsRecorder.ObservePluginDurationAsync(metrics.Unreserve, pl.Name(), framework.Success.String(), metrics.SinceInSeconds(startTime)) -} - -// RunPermitPlugins runs the set of configured permit plugins. If any of these -// plugins returns a status other than "Success" or "Wait", it does not continue -// running the remaining plugins and returns an error. Otherwise, if any of the -// plugins returns "Wait", then this function will create and add waiting pod -// to a map of currently waiting pods and return status with "Wait" code. -// Pod will remain waiting pod for the minimum duration returned by the permit plugins. -func (f *frameworkImpl) RunPermitPlugins(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (status *framework.Status) { - startTime := time.Now() - defer func() { - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Permit, status.Code().String(), f.profileName).Observe(metrics.SinceInSeconds(startTime)) - }() - pluginsWaitTime := make(map[string]time.Duration) - statusCode := framework.Success - logger := klog.FromContext(ctx) - verboseLogs := logger.V(4).Enabled() - if verboseLogs { - logger = klog.LoggerWithName(logger, "Permit") - logger = klog.LoggerWithValues(logger, "node", klog.ObjectRef{Name: nodeName}) - } - for _, pl := range f.permitPlugins { - ctx := ctx - if verboseLogs { - logger := klog.LoggerWithName(logger, pl.Name()) - ctx = klog.NewContext(ctx, logger) - } - status, timeout := f.runPermitPlugin(ctx, pl, state, pod, nodeName) - if !status.IsSuccess() { - if status.IsRejected() { - logger.V(4).Info("Pod rejected by plugin", "pod", klog.KObj(pod), "plugin", pl.Name(), "status", status.Message()) - return status.WithPlugin(pl.Name()) - } - if status.IsWait() { - // Not allowed to be greater than maxTimeout. - if timeout > maxTimeout { - timeout = maxTimeout - } - pluginsWaitTime[pl.Name()] = timeout - statusCode = framework.Wait - } else { - err := status.AsError() - logger.Error(err, "Plugin failed", "plugin", pl.Name(), "pod", klog.KObj(pod)) - return framework.AsStatus(fmt.Errorf("running Permit plugin %q: %w", pl.Name(), err)).WithPlugin(pl.Name()) - } - } - } - if statusCode == framework.Wait { - waitingPod := newWaitingPod(pod, pluginsWaitTime) - f.waitingPods.add(waitingPod) - msg := fmt.Sprintf("one or more plugins asked to wait and no plugin rejected pod %q", pod.Name) - logger.V(4).Info("One or more plugins asked to wait and no plugin rejected pod", "pod", klog.KObj(pod)) - return framework.NewStatus(framework.Wait, msg) - } - return nil -} - -func (f *frameworkImpl) runPermitPlugin(ctx context.Context, pl framework.PermitPlugin, state *framework.CycleState, pod *v1.Pod, nodeName string) (*framework.Status, time.Duration) { - if !state.ShouldRecordPluginMetrics() { - return pl.Permit(ctx, state, pod, nodeName) - } - startTime := time.Now() - status, timeout := pl.Permit(ctx, state, pod, nodeName) - f.metricsRecorder.ObservePluginDurationAsync(metrics.Permit, pl.Name(), status.Code().String(), metrics.SinceInSeconds(startTime)) - return status, timeout -} - -// WaitOnPermit will block, if the pod is a waiting pod, until the waiting pod is rejected or allowed. -func (f *frameworkImpl) WaitOnPermit(ctx context.Context, pod *v1.Pod) *framework.Status { - waitingPod := f.waitingPods.get(pod.UID) - if waitingPod == nil { - return nil - } - defer f.waitingPods.remove(pod.UID) - - logger := klog.FromContext(ctx) - logger.V(4).Info("Pod waiting on permit", "pod", klog.KObj(pod)) - - startTime := time.Now() - s := <-waitingPod.s - metrics.PermitWaitDuration.WithLabelValues(s.Code().String()).Observe(metrics.SinceInSeconds(startTime)) - - if !s.IsSuccess() { - if s.IsRejected() { - logger.V(4).Info("Pod rejected while waiting on permit", "pod", klog.KObj(pod), "status", s.Message()) - return s - } - err := s.AsError() - logger.Error(err, "Failed waiting on permit for pod", "pod", klog.KObj(pod)) - return framework.AsStatus(fmt.Errorf("waiting on permit for pod: %w", err)).WithPlugin(s.Plugin()) - } - return nil -} - -// SnapshotSharedLister returns the scheduler's SharedLister of the latest NodeInfo -// snapshot. The snapshot is taken at the beginning of a scheduling cycle and remains -// unchanged until a pod finishes "Reserve". There is no guarantee that the information -// remains unchanged after "Reserve". -func (f *frameworkImpl) SnapshotSharedLister() framework.SharedLister { - return f.snapshotSharedLister -} - -// IterateOverWaitingPods acquires a read lock and iterates over the WaitingPods map. -func (f *frameworkImpl) IterateOverWaitingPods(callback func(framework.WaitingPod)) { - f.waitingPods.iterate(callback) -} - -// GetWaitingPod returns a reference to a WaitingPod given its UID. -func (f *frameworkImpl) GetWaitingPod(uid types.UID) framework.WaitingPod { - if wp := f.waitingPods.get(uid); wp != nil { - return wp - } - return nil // Returning nil instead of *waitingPod(nil). -} - -// RejectWaitingPod rejects a WaitingPod given its UID. -// The returned value indicates if the given pod is waiting or not. -func (f *frameworkImpl) RejectWaitingPod(uid types.UID) bool { - if waitingPod := f.waitingPods.get(uid); waitingPod != nil { - waitingPod.Reject("", "removed") - return true - } - return false -} - -// HasFilterPlugins returns true if at least one filter plugin is defined. -func (f *frameworkImpl) HasFilterPlugins() bool { - return len(f.filterPlugins) > 0 -} - -// HasPostFilterPlugins returns true if at least one postFilter plugin is defined. -func (f *frameworkImpl) HasPostFilterPlugins() bool { - return len(f.postFilterPlugins) > 0 -} - -// HasScorePlugins returns true if at least one score plugin is defined. -func (f *frameworkImpl) HasScorePlugins() bool { - return len(f.scorePlugins) > 0 -} - -// ListPlugins returns a map of extension point name to plugin names configured at each extension -// point. Returns nil if no plugins where configured. -func (f *frameworkImpl) ListPlugins() *config.Plugins { - m := config.Plugins{} - - for _, e := range f.getExtensionPoints(&m) { - plugins := reflect.ValueOf(e.slicePtr).Elem() - extName := plugins.Type().Elem().Name() - var cfgs []config.Plugin - for i := 0; i < plugins.Len(); i++ { - name := plugins.Index(i).Interface().(framework.Plugin).Name() - p := config.Plugin{Name: name} - if extName == "ScorePlugin" { - // Weights apply only to score plugins. - p.Weight = int32(f.scorePluginWeight[name]) - } - cfgs = append(cfgs, p) - } - if len(cfgs) > 0 { - e.plugins.Enabled = cfgs - } - } - return &m -} - -// ClientSet returns a kubernetes clientset. -func (f *frameworkImpl) ClientSet() clientset.Interface { - return f.clientSet -} - -// KubeConfig returns a kubernetes config. -func (f *frameworkImpl) KubeConfig() *restclient.Config { - return f.kubeConfig -} - -// EventRecorder returns an event recorder. -func (f *frameworkImpl) EventRecorder() events.EventRecorder { - return f.eventRecorder -} - -// SharedInformerFactory returns a shared informer factory. -func (f *frameworkImpl) SharedInformerFactory() informers.SharedInformerFactory { - return f.informerFactory -} - -// SharedDRAManager returns the SharedDRAManager of the framework. -func (f *frameworkImpl) SharedDRAManager() framework.SharedDRAManager { - return f.sharedDRAManager -} - -func (f *frameworkImpl) pluginsNeeded(plugins *config.Plugins) sets.Set[string] { - pgSet := sets.Set[string]{} - - if plugins == nil { - return pgSet - } - - find := func(pgs *config.PluginSet) { - for _, pg := range pgs.Enabled { - pgSet.Insert(pg.Name) - } - } - - for _, e := range f.getExtensionPoints(plugins) { - find(e.plugins) - } - // Parse MultiPoint separately since they are not returned by f.getExtensionPoints() - find(&plugins.MultiPoint) - - return pgSet -} - -// ProfileName returns the profile name associated to this framework. -func (f *frameworkImpl) ProfileName() string { - return f.profileName -} - -// PercentageOfNodesToScore returns percentageOfNodesToScore associated to a profile. -func (f *frameworkImpl) PercentageOfNodesToScore() *int32 { - return f.percentageOfNodesToScore -} - -// Parallelizer returns a parallelizer holding parallelism for scheduler. -func (f *frameworkImpl) Parallelizer() parallelize.Parallelizer { - return f.parallelizer -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/instrumented_plugins.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/instrumented_plugins.go deleted file mode 100644 index 04e9004c8..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/instrumented_plugins.go +++ /dev/null @@ -1,83 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package runtime - -import ( - "context" - - v1 "k8s.io/api/core/v1" - compbasemetrics "k8s.io/component-base/metrics" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -type instrumentedFilterPlugin struct { - framework.FilterPlugin - - metric compbasemetrics.CounterMetric -} - -var _ framework.FilterPlugin = &instrumentedFilterPlugin{} - -func (p *instrumentedFilterPlugin) Filter(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) *framework.Status { - p.metric.Inc() - return p.FilterPlugin.Filter(ctx, state, pod, nodeInfo) -} - -type instrumentedPreFilterPlugin struct { - framework.PreFilterPlugin - - metric compbasemetrics.CounterMetric -} - -var _ framework.PreFilterPlugin = &instrumentedPreFilterPlugin{} - -func (p *instrumentedPreFilterPlugin) PreFilter(ctx context.Context, state *framework.CycleState, pod *v1.Pod) (*framework.PreFilterResult, *framework.Status) { - result, status := p.PreFilterPlugin.PreFilter(ctx, state, pod) - if !status.IsSkip() { - p.metric.Inc() - } - return result, status -} - -type instrumentedPreScorePlugin struct { - framework.PreScorePlugin - - metric compbasemetrics.CounterMetric -} - -var _ framework.PreScorePlugin = &instrumentedPreScorePlugin{} - -func (p *instrumentedPreScorePlugin) PreScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodes []*framework.NodeInfo) *framework.Status { - status := p.PreScorePlugin.PreScore(ctx, state, pod, nodes) - if !status.IsSkip() { - p.metric.Inc() - } - return status -} - -type instrumentedScorePlugin struct { - framework.ScorePlugin - - metric compbasemetrics.CounterMetric -} - -var _ framework.ScorePlugin = &instrumentedScorePlugin{} - -func (p *instrumentedScorePlugin) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeInfo *framework.NodeInfo) (int64, *framework.Status) { - p.metric.Inc() - return p.ScorePlugin.Score(ctx, state, pod, nodeInfo) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/registry.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/registry.go deleted file mode 100644 index b6fca3c29..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/registry.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package runtime - -import ( - "context" - "fmt" - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/util/json" - "k8s.io/kubernetes/pkg/scheduler/framework" - plfeature "k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature" - "sigs.k8s.io/yaml" -) - -// PluginFactory is a function that builds a plugin. -type PluginFactory = func(ctx context.Context, configuration runtime.Object, f framework.Handle) (framework.Plugin, error) - -// PluginFactoryWithFts is a function that builds a plugin with certain feature gates. -type PluginFactoryWithFts func(context.Context, runtime.Object, framework.Handle, plfeature.Features) (framework.Plugin, error) - -// FactoryAdapter can be used to inject feature gates for a plugin that needs -// them when the caller expects the older PluginFactory method. -func FactoryAdapter(fts plfeature.Features, withFts PluginFactoryWithFts) PluginFactory { - return func(ctx context.Context, plArgs runtime.Object, fh framework.Handle) (framework.Plugin, error) { - return withFts(ctx, plArgs, fh, fts) - } -} - -// DecodeInto decodes configuration whose type is *runtime.Unknown to the interface into. -func DecodeInto(obj runtime.Object, into interface{}) error { - if obj == nil { - return nil - } - configuration, ok := obj.(*runtime.Unknown) - if !ok { - return fmt.Errorf("want args of type runtime.Unknown, got %T", obj) - } - if configuration.Raw == nil { - return nil - } - - switch configuration.ContentType { - // If ContentType is empty, it means ContentTypeJSON by default. - case runtime.ContentTypeJSON, "": - return json.Unmarshal(configuration.Raw, into) - case runtime.ContentTypeYAML: - return yaml.Unmarshal(configuration.Raw, into) - default: - return fmt.Errorf("not supported content type %s", configuration.ContentType) - } -} - -// Registry is a collection of all available plugins. The framework uses a -// registry to enable and initialize configured plugins. -// All plugins must be in the registry before initializing the framework. -type Registry map[string]PluginFactory - -// Register adds a new plugin to the registry. If a plugin with the same name -// exists, it returns an error. -func (r Registry) Register(name string, factory PluginFactory) error { - if _, ok := r[name]; ok { - return fmt.Errorf("a plugin named %v already exists", name) - } - r[name] = factory - return nil -} - -// Unregister removes an existing plugin from the registry. If no plugin with -// the provided name exists, it returns an error. -func (r Registry) Unregister(name string) error { - if _, ok := r[name]; !ok { - return fmt.Errorf("no plugin named %v exists", name) - } - delete(r, name) - return nil -} - -// Merge merges the provided registry to the current one. -func (r Registry) Merge(in Registry) error { - for name, factory := range in { - if err := r.Register(name, factory); err != nil { - return err - } - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go deleted file mode 100644 index 3d40d4a52..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/runtime/waiting_pods_map.go +++ /dev/null @@ -1,165 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package runtime - -import ( - "fmt" - "sync" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/kubernetes/pkg/scheduler/framework" -) - -// waitingPodsMap a thread-safe map used to maintain pods waiting in the permit phase. -type waitingPodsMap struct { - pods map[types.UID]*waitingPod - mu sync.RWMutex -} - -// NewWaitingPodsMap returns a new waitingPodsMap. -func NewWaitingPodsMap() *waitingPodsMap { - return &waitingPodsMap{ - pods: make(map[types.UID]*waitingPod), - } -} - -// add a new WaitingPod to the map. -func (m *waitingPodsMap) add(wp *waitingPod) { - m.mu.Lock() - defer m.mu.Unlock() - m.pods[wp.GetPod().UID] = wp -} - -// remove a WaitingPod from the map. -func (m *waitingPodsMap) remove(uid types.UID) { - m.mu.Lock() - defer m.mu.Unlock() - delete(m.pods, uid) -} - -// get a WaitingPod from the map. -func (m *waitingPodsMap) get(uid types.UID) *waitingPod { - m.mu.RLock() - defer m.mu.RUnlock() - return m.pods[uid] -} - -// iterate acquires a read lock and iterates over the WaitingPods map. -func (m *waitingPodsMap) iterate(callback func(framework.WaitingPod)) { - m.mu.RLock() - defer m.mu.RUnlock() - for _, v := range m.pods { - callback(v) - } -} - -// waitingPod represents a pod waiting in the permit phase. -type waitingPod struct { - pod *v1.Pod - pendingPlugins map[string]*time.Timer - s chan *framework.Status - mu sync.RWMutex -} - -var _ framework.WaitingPod = &waitingPod{} - -// newWaitingPod returns a new waitingPod instance. -func newWaitingPod(pod *v1.Pod, pluginsMaxWaitTime map[string]time.Duration) *waitingPod { - wp := &waitingPod{ - pod: pod, - // Allow() and Reject() calls are non-blocking. This property is guaranteed - // by using non-blocking send to this channel. This channel has a buffer of size 1 - // to ensure that non-blocking send will not be ignored - possible situation when - // receiving from this channel happens after non-blocking send. - s: make(chan *framework.Status, 1), - } - - wp.pendingPlugins = make(map[string]*time.Timer, len(pluginsMaxWaitTime)) - // The time.AfterFunc calls wp.Reject which iterates through pendingPlugins map. Acquire the - // lock here so that time.AfterFunc can only execute after newWaitingPod finishes. - wp.mu.Lock() - defer wp.mu.Unlock() - for k, v := range pluginsMaxWaitTime { - plugin, waitTime := k, v - wp.pendingPlugins[plugin] = time.AfterFunc(waitTime, func() { - msg := fmt.Sprintf("rejected due to timeout after waiting %v at plugin %v", - waitTime, plugin) - wp.Reject(plugin, msg) - }) - } - - return wp -} - -// GetPod returns a reference to the waiting pod. -func (w *waitingPod) GetPod() *v1.Pod { - return w.pod -} - -// GetPendingPlugins returns a list of pending permit plugin's name. -func (w *waitingPod) GetPendingPlugins() []string { - w.mu.RLock() - defer w.mu.RUnlock() - plugins := make([]string, 0, len(w.pendingPlugins)) - for p := range w.pendingPlugins { - plugins = append(plugins, p) - } - - return plugins -} - -// Allow declares the waiting pod is allowed to be scheduled by plugin pluginName. -// If this is the last remaining plugin to allow, then a success signal is delivered -// to unblock the pod. -func (w *waitingPod) Allow(pluginName string) { - w.mu.Lock() - defer w.mu.Unlock() - if timer, exist := w.pendingPlugins[pluginName]; exist { - timer.Stop() - delete(w.pendingPlugins, pluginName) - } - - // Only signal success status after all plugins have allowed - if len(w.pendingPlugins) != 0 { - return - } - - // The select clause works as a non-blocking send. - // If there is no receiver, it's a no-op (default case). - select { - case w.s <- framework.NewStatus(framework.Success, ""): - default: - } -} - -// Reject declares the waiting pod unschedulable. -func (w *waitingPod) Reject(pluginName, msg string) { - w.mu.RLock() - defer w.mu.RUnlock() - for _, timer := range w.pendingPlugins { - timer.Stop() - } - - // The select clause works as a non-blocking send. - // If there is no receiver, it's a no-op (default case). - select { - case w.s <- framework.NewStatus(framework.Unschedulable, msg).WithPlugin(pluginName): - default: - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go b/vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go deleted file mode 100644 index 8c3a7bde7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/framework/types.go +++ /dev/null @@ -1,1334 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package framework - -import ( - "errors" - "fmt" - "sort" - "strings" - "sync/atomic" - "time" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - utilerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/sets" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/klog/v2" - - "k8s.io/apimachinery/pkg/api/resource" - resourcehelper "k8s.io/component-helpers/resource" - "k8s.io/kubernetes/pkg/features" - schedutil "k8s.io/kubernetes/pkg/scheduler/util" -) - -var generation int64 - -// ActionType is an integer to represent one type of resource change. -// Different ActionTypes can be bit-wised to compose new semantics. -type ActionType int64 - -// Constants for ActionTypes. -// CAUTION for contributors: When you add a new ActionType, you must update the following: -// - The list of basic, podOnly, and nodeOnly. -// - String() method. -const ( - Add ActionType = 1 << iota - Delete - - // UpdateNodeXYZ is only applicable for Node events. - // If you use UpdateNodeXYZ, - // your plugin's QueueingHint is only executed for the specific sub-Update event. - // It's better to narrow down the scope of the event by using them instead of just using Update event - // for better performance in requeueing. - UpdateNodeAllocatable - UpdateNodeLabel - // UpdateNodeTaint is an update for node's taints or node.Spec.Unschedulable. - UpdateNodeTaint - UpdateNodeCondition - UpdateNodeAnnotation - - // UpdatePodXYZ is only applicable for Pod events. - // If you use UpdatePodXYZ, - // your plugin's QueueingHint is only executed for the specific sub-Update event. - // It's better to narrow down the scope of the event by using them instead of Update event - // for better performance in requeueing. - UpdatePodLabel - // UpdatePodScaleDown is an update for pod's scale down (i.e., any resource request is reduced). - UpdatePodScaleDown - // UpdatePodToleration is an addition for pod's tolerations. - // (Due to API validation, we can add, but cannot modify or remove tolerations.) - UpdatePodToleration - // UpdatePodSchedulingGatesEliminated is an update for pod's scheduling gates, which eliminates all scheduling gates in the Pod. - UpdatePodSchedulingGatesEliminated - // UpdatePodGeneratedResourceClaim is an update of the list of ResourceClaims generated for the pod. - // Depends on the DynamicResourceAllocation feature gate. - UpdatePodGeneratedResourceClaim - - // updatePodOther is a update for pod's other fields. - // It's used only for the internal event handling, and thus unexported. - updatePodOther - - All ActionType = 1<. . ." -func (f *FitError) Error() string { - reasonMsg := fmt.Sprintf(NoNodeAvailableMsg+":", f.NumAllNodes) - preFilterMsg := f.Diagnosis.PreFilterMsg - if preFilterMsg != "" { - // PreFilter plugin returns unschedulable. - // Add the messages from PreFilter plugins to reasonMsg. - reasonMsg += fmt.Sprintf(" %v.", preFilterMsg) - } - - if preFilterMsg == "" { - // the scheduling cycle went through PreFilter extension point successfully. - // - // When the prefilter plugin returns unschedulable, - // the scheduling framework inserts the same unschedulable status to all nodes in NodeToStatusMap. - // So, we shouldn't add the message from NodeToStatusMap when the PreFilter failed. - // Otherwise, we will have duplicated reasons in the error message. - reasons := make(map[string]int) - f.Diagnosis.NodeToStatus.ForEachExplicitNode(func(_ string, status *Status) { - for _, reason := range status.Reasons() { - reasons[reason]++ - } - }) - if f.Diagnosis.NodeToStatus.Len() < f.NumAllNodes { - // Adding predefined reasons for nodes that are absent in NodeToStatusMap - for _, reason := range f.Diagnosis.NodeToStatus.AbsentNodesStatus().Reasons() { - reasons[reason] += f.NumAllNodes - f.Diagnosis.NodeToStatus.Len() - } - } - - sortReasonsHistogram := func() []string { - var reasonStrings []string - for k, v := range reasons { - reasonStrings = append(reasonStrings, fmt.Sprintf("%v %v", v, k)) - } - sort.Strings(reasonStrings) - return reasonStrings - } - sortedFilterMsg := sortReasonsHistogram() - if len(sortedFilterMsg) != 0 { - reasonMsg += fmt.Sprintf(" %v.", strings.Join(sortedFilterMsg, ", ")) - } - } - - // Add the messages from PostFilter plugins to reasonMsg. - // We can add this message regardless of whether the scheduling cycle fails at PreFilter or Filter - // since we may run PostFilter (if enabled) in both cases. - postFilterMsg := f.Diagnosis.PostFilterMsg - if postFilterMsg != "" { - reasonMsg += fmt.Sprintf(" %v", postFilterMsg) - } - return reasonMsg -} - -func newAffinityTerm(pod *v1.Pod, term *v1.PodAffinityTerm) (*AffinityTerm, error) { - selector, err := metav1.LabelSelectorAsSelector(term.LabelSelector) - if err != nil { - return nil, err - } - - namespaces := getNamespacesFromPodAffinityTerm(pod, term) - nsSelector, err := metav1.LabelSelectorAsSelector(term.NamespaceSelector) - if err != nil { - return nil, err - } - - return &AffinityTerm{Namespaces: namespaces, Selector: selector, TopologyKey: term.TopologyKey, NamespaceSelector: nsSelector}, nil -} - -// GetAffinityTerms receives a Pod and affinity terms and returns the namespaces and -// selectors of the terms. -func GetAffinityTerms(pod *v1.Pod, v1Terms []v1.PodAffinityTerm) ([]AffinityTerm, error) { - if v1Terms == nil { - return nil, nil - } - - var terms []AffinityTerm - for i := range v1Terms { - t, err := newAffinityTerm(pod, &v1Terms[i]) - if err != nil { - // We get here if the label selector failed to process - return nil, err - } - terms = append(terms, *t) - } - return terms, nil -} - -// getWeightedAffinityTerms returns the list of processed affinity terms. -func getWeightedAffinityTerms(pod *v1.Pod, v1Terms []v1.WeightedPodAffinityTerm) ([]WeightedAffinityTerm, error) { - if v1Terms == nil { - return nil, nil - } - - var terms []WeightedAffinityTerm - for i := range v1Terms { - t, err := newAffinityTerm(pod, &v1Terms[i].PodAffinityTerm) - if err != nil { - // We get here if the label selector failed to process - return nil, err - } - terms = append(terms, WeightedAffinityTerm{AffinityTerm: *t, Weight: v1Terms[i].Weight}) - } - return terms, nil -} - -// NewPodInfo returns a new PodInfo. -func NewPodInfo(pod *v1.Pod) (*PodInfo, error) { - pInfo := &PodInfo{} - err := pInfo.Update(pod) - return pInfo, err -} - -func GetPodAffinityTerms(affinity *v1.Affinity) (terms []v1.PodAffinityTerm) { - if affinity != nil && affinity.PodAffinity != nil { - if len(affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 { - terms = affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution - } - // TODO: Uncomment this block when implement RequiredDuringSchedulingRequiredDuringExecution. - // if len(affinity.PodAffinity.RequiredDuringSchedulingRequiredDuringExecution) != 0 { - // terms = append(terms, affinity.PodAffinity.RequiredDuringSchedulingRequiredDuringExecution...) - // } - } - return terms -} - -func GetPodAntiAffinityTerms(affinity *v1.Affinity) (terms []v1.PodAffinityTerm) { - if affinity != nil && affinity.PodAntiAffinity != nil { - if len(affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 { - terms = affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution - } - // TODO: Uncomment this block when implement RequiredDuringSchedulingRequiredDuringExecution. - // if len(affinity.PodAntiAffinity.RequiredDuringSchedulingRequiredDuringExecution) != 0 { - // terms = append(terms, affinity.PodAntiAffinity.RequiredDuringSchedulingRequiredDuringExecution...) - // } - } - return terms -} - -// returns a set of names according to the namespaces indicated in podAffinityTerm. -// If namespaces is empty it considers the given pod's namespace. -func getNamespacesFromPodAffinityTerm(pod *v1.Pod, podAffinityTerm *v1.PodAffinityTerm) sets.Set[string] { - names := sets.Set[string]{} - if len(podAffinityTerm.Namespaces) == 0 && podAffinityTerm.NamespaceSelector == nil { - names.Insert(pod.Namespace) - } else { - names.Insert(podAffinityTerm.Namespaces...) - } - return names -} - -// ImageStateSummary provides summarized information about the state of an image. -type ImageStateSummary struct { - // Size of the image - Size int64 - // Used to track how many nodes have this image, it is computed from the Nodes field below - // during the execution of Snapshot. - NumNodes int - // A set of node names for nodes having this image present. This field is used for - // keeping track of the nodes during update/add/remove events. - Nodes sets.Set[string] -} - -// Snapshot returns a copy without Nodes field of ImageStateSummary -func (iss *ImageStateSummary) Snapshot() *ImageStateSummary { - return &ImageStateSummary{ - Size: iss.Size, - NumNodes: iss.Nodes.Len(), - } -} - -// NodeInfo is node level aggregated information. -type NodeInfo struct { - // Overall node information. - node *v1.Node - - // Pods running on the node. - Pods []*PodInfo - - // The subset of pods with affinity. - PodsWithAffinity []*PodInfo - - // The subset of pods with required anti-affinity. - PodsWithRequiredAntiAffinity []*PodInfo - - // Ports allocated on the node. - UsedPorts HostPortInfo - - // Total requested resources of all pods on this node. This includes assumed - // pods, which scheduler has sent for binding, but may not be scheduled yet. - Requested *Resource - // Total requested resources of all pods on this node with a minimum value - // applied to each container's CPU and memory requests. This does not reflect - // the actual resource requests for this node, but is used to avoid scheduling - // many zero-request pods onto one node. - NonZeroRequested *Resource - // We store allocatedResources (which is Node.Status.Allocatable.*) explicitly - // as int64, to avoid conversions and accessing map. - Allocatable *Resource - - // ImageStates holds the entry of an image if and only if this image is on the node. The entry can be used for - // checking an image's existence and advanced usage (e.g., image locality scheduling policy) based on the image - // state information. - ImageStates map[string]*ImageStateSummary - - // PVCRefCounts contains a mapping of PVC names to the number of pods on the node using it. - // Keys are in the format "namespace/name". - PVCRefCounts map[string]int - - // Whenever NodeInfo changes, generation is bumped. - // This is used to avoid cloning it if the object didn't change. - Generation int64 -} - -// NodeInfo implements KMetadata, so for example klog.KObjSlice(nodes) works -// when nodes is a []*NodeInfo. -var _ klog.KMetadata = &NodeInfo{} - -func (n *NodeInfo) GetName() string { - if n == nil { - return "" - } - if n.node == nil { - return "" - } - return n.node.Name -} -func (n *NodeInfo) GetNamespace() string { return "" } - -// nextGeneration: Let's make sure history never forgets the name... -// Increments the generation number monotonically ensuring that generation numbers never collide. -// Collision of the generation numbers would be particularly problematic if a node was deleted and -// added back with the same name. See issue#63262. -func nextGeneration() int64 { - return atomic.AddInt64(&generation, 1) -} - -// Resource is a collection of compute resource. -type Resource struct { - MilliCPU int64 - Memory int64 - EphemeralStorage int64 - // We store allowedPodNumber (which is Node.Status.Allocatable.Pods().Value()) - // explicitly as int, to avoid conversions and improve performance. - AllowedPodNumber int - // ScalarResources - ScalarResources map[v1.ResourceName]int64 -} - -// NewResource creates a Resource from ResourceList -func NewResource(rl v1.ResourceList) *Resource { - r := &Resource{} - r.Add(rl) - return r -} - -// Add adds ResourceList into Resource. -func (r *Resource) Add(rl v1.ResourceList) { - if r == nil { - return - } - - for rName, rQuant := range rl { - switch rName { - case v1.ResourceCPU: - r.MilliCPU += rQuant.MilliValue() - case v1.ResourceMemory: - r.Memory += rQuant.Value() - case v1.ResourcePods: - r.AllowedPodNumber += int(rQuant.Value()) - case v1.ResourceEphemeralStorage: - r.EphemeralStorage += rQuant.Value() - default: - if schedutil.IsScalarResourceName(rName) { - r.AddScalar(rName, rQuant.Value()) - } - } - } -} - -// Clone returns a copy of this resource. -func (r *Resource) Clone() *Resource { - res := &Resource{ - MilliCPU: r.MilliCPU, - Memory: r.Memory, - AllowedPodNumber: r.AllowedPodNumber, - EphemeralStorage: r.EphemeralStorage, - } - if r.ScalarResources != nil { - res.ScalarResources = make(map[v1.ResourceName]int64, len(r.ScalarResources)) - for k, v := range r.ScalarResources { - res.ScalarResources[k] = v - } - } - return res -} - -// AddScalar adds a resource by a scalar value of this resource. -func (r *Resource) AddScalar(name v1.ResourceName, quantity int64) { - r.SetScalar(name, r.ScalarResources[name]+quantity) -} - -// SetScalar sets a resource by a scalar value of this resource. -func (r *Resource) SetScalar(name v1.ResourceName, quantity int64) { - // Lazily allocate scalar resource map. - if r.ScalarResources == nil { - r.ScalarResources = map[v1.ResourceName]int64{} - } - r.ScalarResources[name] = quantity -} - -// SetMaxResource compares with ResourceList and takes max value for each Resource. -func (r *Resource) SetMaxResource(rl v1.ResourceList) { - if r == nil { - return - } - - for rName, rQuantity := range rl { - switch rName { - case v1.ResourceMemory: - r.Memory = max(r.Memory, rQuantity.Value()) - case v1.ResourceCPU: - r.MilliCPU = max(r.MilliCPU, rQuantity.MilliValue()) - case v1.ResourceEphemeralStorage: - r.EphemeralStorage = max(r.EphemeralStorage, rQuantity.Value()) - default: - if schedutil.IsScalarResourceName(rName) { - r.SetScalar(rName, max(r.ScalarResources[rName], rQuantity.Value())) - } - } - } -} - -// NewNodeInfo returns a ready to use empty NodeInfo object. -// If any pods are given in arguments, their information will be aggregated in -// the returned object. -func NewNodeInfo(pods ...*v1.Pod) *NodeInfo { - ni := &NodeInfo{ - Requested: &Resource{}, - NonZeroRequested: &Resource{}, - Allocatable: &Resource{}, - Generation: nextGeneration(), - UsedPorts: make(HostPortInfo), - ImageStates: make(map[string]*ImageStateSummary), - PVCRefCounts: make(map[string]int), - } - for _, pod := range pods { - ni.AddPod(pod) - } - return ni -} - -// Node returns overall information about this node. -func (n *NodeInfo) Node() *v1.Node { - if n == nil { - return nil - } - return n.node -} - -// Snapshot returns a copy of this node, Except that ImageStates is copied without the Nodes field. -func (n *NodeInfo) Snapshot() *NodeInfo { - clone := &NodeInfo{ - node: n.node, - Requested: n.Requested.Clone(), - NonZeroRequested: n.NonZeroRequested.Clone(), - Allocatable: n.Allocatable.Clone(), - UsedPorts: make(HostPortInfo), - ImageStates: make(map[string]*ImageStateSummary), - PVCRefCounts: make(map[string]int), - Generation: n.Generation, - } - if len(n.Pods) > 0 { - clone.Pods = append([]*PodInfo(nil), n.Pods...) - } - if len(n.UsedPorts) > 0 { - // HostPortInfo is a map-in-map struct - // make sure it's deep copied - for ip, portMap := range n.UsedPorts { - clone.UsedPorts[ip] = make(map[ProtocolPort]struct{}) - for protocolPort, v := range portMap { - clone.UsedPorts[ip][protocolPort] = v - } - } - } - if len(n.PodsWithAffinity) > 0 { - clone.PodsWithAffinity = append([]*PodInfo(nil), n.PodsWithAffinity...) - } - if len(n.PodsWithRequiredAntiAffinity) > 0 { - clone.PodsWithRequiredAntiAffinity = append([]*PodInfo(nil), n.PodsWithRequiredAntiAffinity...) - } - if len(n.ImageStates) > 0 { - state := make(map[string]*ImageStateSummary, len(n.ImageStates)) - for imageName, imageState := range n.ImageStates { - state[imageName] = imageState.Snapshot() - } - clone.ImageStates = state - } - for key, value := range n.PVCRefCounts { - clone.PVCRefCounts[key] = value - } - return clone -} - -// String returns representation of human readable format of this NodeInfo. -func (n *NodeInfo) String() string { - podKeys := make([]string, len(n.Pods)) - for i, p := range n.Pods { - podKeys[i] = p.Pod.Name - } - return fmt.Sprintf("&NodeInfo{Pods:%v, RequestedResource:%#v, NonZeroRequest: %#v, UsedPort: %#v, AllocatableResource:%#v}", - podKeys, n.Requested, n.NonZeroRequested, n.UsedPorts, n.Allocatable) -} - -// AddPodInfo adds pod information to this NodeInfo. -// Consider using this instead of AddPod if a PodInfo is already computed. -func (n *NodeInfo) AddPodInfo(podInfo *PodInfo) { - n.Pods = append(n.Pods, podInfo) - if podWithAffinity(podInfo.Pod) { - n.PodsWithAffinity = append(n.PodsWithAffinity, podInfo) - } - if podWithRequiredAntiAffinity(podInfo.Pod) { - n.PodsWithRequiredAntiAffinity = append(n.PodsWithRequiredAntiAffinity, podInfo) - } - n.update(podInfo, 1) -} - -// AddPod is a wrapper around AddPodInfo. -func (n *NodeInfo) AddPod(pod *v1.Pod) { - // ignore this err since apiserver doesn't properly validate affinity terms - // and we can't fix the validation for backwards compatibility. - podInfo, _ := NewPodInfo(pod) - n.AddPodInfo(podInfo) -} - -func podWithAffinity(p *v1.Pod) bool { - affinity := p.Spec.Affinity - return affinity != nil && (affinity.PodAffinity != nil || affinity.PodAntiAffinity != nil) -} - -func podWithRequiredAntiAffinity(p *v1.Pod) bool { - affinity := p.Spec.Affinity - return affinity != nil && affinity.PodAntiAffinity != nil && - len(affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution) != 0 -} - -func removeFromSlice(logger klog.Logger, s []*PodInfo, k string) ([]*PodInfo, *PodInfo) { - var removedPod *PodInfo - for i := range s { - tmpKey, err := GetPodKey(s[i].Pod) - if err != nil { - logger.Error(err, "Cannot get pod key", "pod", klog.KObj(s[i].Pod)) - continue - } - if k == tmpKey { - removedPod = s[i] - // delete the element - s[i] = s[len(s)-1] - s = s[:len(s)-1] - break - } - } - // resets the slices to nil so that we can do DeepEqual in unit tests. - if len(s) == 0 { - return nil, removedPod - } - return s, removedPod -} - -// RemovePod subtracts pod information from this NodeInfo. -func (n *NodeInfo) RemovePod(logger klog.Logger, pod *v1.Pod) error { - k, err := GetPodKey(pod) - if err != nil { - return err - } - if podWithAffinity(pod) { - n.PodsWithAffinity, _ = removeFromSlice(logger, n.PodsWithAffinity, k) - } - if podWithRequiredAntiAffinity(pod) { - n.PodsWithRequiredAntiAffinity, _ = removeFromSlice(logger, n.PodsWithRequiredAntiAffinity, k) - } - - var removedPod *PodInfo - if n.Pods, removedPod = removeFromSlice(logger, n.Pods, k); removedPod != nil { - n.update(removedPod, -1) - return nil - } - return fmt.Errorf("no corresponding pod %s in pods of node %s", pod.Name, n.node.Name) -} - -// update node info based on the pod, and sign. -// The sign will be set to `+1` when AddPod and to `-1` when RemovePod. -func (n *NodeInfo) update(podInfo *PodInfo, sign int64) { - podResource := podInfo.calculateResource() - n.Requested.MilliCPU += sign * podResource.resource.MilliCPU - n.Requested.Memory += sign * podResource.resource.Memory - n.Requested.EphemeralStorage += sign * podResource.resource.EphemeralStorage - if n.Requested.ScalarResources == nil && len(podResource.resource.ScalarResources) > 0 { - n.Requested.ScalarResources = map[v1.ResourceName]int64{} - } - for rName, rQuant := range podResource.resource.ScalarResources { - n.Requested.ScalarResources[rName] += sign * rQuant - } - n.NonZeroRequested.MilliCPU += sign * podResource.non0CPU - n.NonZeroRequested.Memory += sign * podResource.non0Mem - - // Consume ports when pod added or release ports when pod removed. - n.updateUsedPorts(podInfo.Pod, sign > 0) - n.updatePVCRefCounts(podInfo.Pod, sign > 0) - - n.Generation = nextGeneration() -} - -// getNonMissingContainerRequests returns the default non-zero CPU and memory -// requests for a container that the scheduler uses when container-level and -// pod-level requests are not set for a resource. It returns a ResourceList that -// includes these default non-zero requests, which are essential for the -// scheduler to function correctly. -// The method's behavior depends on whether pod-level resources are set or not: -// 1. When the pod level resources are not set, the method returns a ResourceList -// with the following defaults: -// - CPU: schedutil.DefaultMilliCPURequest -// - Memory: schedutil.DefaultMemoryRequest -// -// These defaults ensure that each container has a minimum resource request, -// allowing the scheduler to aggregate these requests and find a suitable node -// for the pod. -// -// 2. When the pod level resources are set, if a CPU or memory request is -// missing at the container-level *and* at the pod-level, the corresponding -// default value (schedutil.DefaultMilliCPURequest or schedutil.DefaultMemoryRequest) -// is included in the returned ResourceList. -// Note that these default values are not set in the Pod object itself, they are only used -// by the scheduler during node selection. -func getNonMissingContainerRequests(requests v1.ResourceList, podLevelResourcesSet bool) v1.ResourceList { - if !podLevelResourcesSet { - return v1.ResourceList{ - v1.ResourceCPU: *resource.NewMilliQuantity(schedutil.DefaultMilliCPURequest, resource.DecimalSI), - v1.ResourceMemory: *resource.NewQuantity(schedutil.DefaultMemoryRequest, resource.DecimalSI), - } - } - - nonMissingContainerRequests := make(v1.ResourceList, 2) - // DefaultMilliCPURequest serves as the fallback value when both - // pod-level and container-level CPU requests are not set. - // Note that the apiserver defaulting logic will propagate a non-zero - // container-level CPU request to the pod level if a pod-level request - // is not explicitly set. - if _, exists := requests[v1.ResourceCPU]; !exists { - nonMissingContainerRequests[v1.ResourceCPU] = *resource.NewMilliQuantity(schedutil.DefaultMilliCPURequest, resource.DecimalSI) - } - - // DefaultMemoryRequest serves as the fallback value when both - // pod-level and container-level CPU requests are unspecified. - // Note that the apiserver defaulting logic will propagate a non-zero - // container-level memory request to the pod level if a pod-level request - // is not explicitly set. - if _, exists := requests[v1.ResourceMemory]; !exists { - nonMissingContainerRequests[v1.ResourceMemory] = *resource.NewQuantity(schedutil.DefaultMemoryRequest, resource.DecimalSI) - } - return nonMissingContainerRequests - -} - -func (pi *PodInfo) calculateResource() podResource { - if pi.cachedResource != nil { - return *pi.cachedResource - } - inPlacePodVerticalScalingEnabled := utilfeature.DefaultFeatureGate.Enabled(features.InPlacePodVerticalScaling) - podLevelResourcesEnabled := utilfeature.DefaultFeatureGate.Enabled(features.PodLevelResources) - requests := resourcehelper.PodRequests(pi.Pod, resourcehelper.PodResourcesOptions{ - UseStatusResources: inPlacePodVerticalScalingEnabled, - // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !podLevelResourcesEnabled, - }) - isPodLevelResourcesSet := podLevelResourcesEnabled && resourcehelper.IsPodLevelRequestsSet(pi.Pod) - nonMissingContainerRequests := getNonMissingContainerRequests(requests, isPodLevelResourcesSet) - non0Requests := requests - if len(nonMissingContainerRequests) > 0 { - non0Requests = resourcehelper.PodRequests(pi.Pod, resourcehelper.PodResourcesOptions{ - UseStatusResources: inPlacePodVerticalScalingEnabled, - // SkipPodLevelResources is set to false when PodLevelResources feature is enabled. - SkipPodLevelResources: !podLevelResourcesEnabled, - NonMissingContainerRequests: nonMissingContainerRequests, - }) - } - non0CPU := non0Requests[v1.ResourceCPU] - non0Mem := non0Requests[v1.ResourceMemory] - - var res Resource - res.Add(requests) - podResource := podResource{ - resource: res, - non0CPU: non0CPU.MilliValue(), - non0Mem: non0Mem.Value(), - } - pi.cachedResource = &podResource - return podResource -} - -// updateUsedPorts updates the UsedPorts of NodeInfo. -func (n *NodeInfo) updateUsedPorts(pod *v1.Pod, add bool) { - for _, port := range schedutil.GetHostPorts(pod) { - if add { - n.UsedPorts.Add(port.HostIP, string(port.Protocol), port.HostPort) - } else { - n.UsedPorts.Remove(port.HostIP, string(port.Protocol), port.HostPort) - } - } -} - -// updatePVCRefCounts updates the PVCRefCounts of NodeInfo. -func (n *NodeInfo) updatePVCRefCounts(pod *v1.Pod, add bool) { - for _, v := range pod.Spec.Volumes { - if v.PersistentVolumeClaim == nil { - continue - } - - key := GetNamespacedName(pod.Namespace, v.PersistentVolumeClaim.ClaimName) - if add { - n.PVCRefCounts[key] += 1 - } else { - n.PVCRefCounts[key] -= 1 - if n.PVCRefCounts[key] <= 0 { - delete(n.PVCRefCounts, key) - } - } - } -} - -// SetNode sets the overall node information. -func (n *NodeInfo) SetNode(node *v1.Node) { - n.node = node - n.Allocatable = NewResource(node.Status.Allocatable) - n.Generation = nextGeneration() -} - -// RemoveNode removes the node object, leaving all other tracking information. -func (n *NodeInfo) RemoveNode() { - n.node = nil - n.Generation = nextGeneration() -} - -// GetPodKey returns the string key of a pod. -func GetPodKey(pod *v1.Pod) (string, error) { - uid := string(pod.UID) - if len(uid) == 0 { - return "", errors.New("cannot get cache key for pod with empty UID") - } - return uid, nil -} - -// GetNamespacedName returns the string format of a namespaced resource name. -func GetNamespacedName(namespace, name string) string { - return fmt.Sprintf("%s/%s", namespace, name) -} - -// DefaultBindAllHostIP defines the default ip address used to bind to all host. -const DefaultBindAllHostIP = "0.0.0.0" - -// ProtocolPort represents a protocol port pair, e.g. tcp:80. -type ProtocolPort struct { - Protocol string - Port int32 -} - -// NewProtocolPort creates a ProtocolPort instance. -func NewProtocolPort(protocol string, port int32) *ProtocolPort { - pp := &ProtocolPort{ - Protocol: protocol, - Port: port, - } - - if len(pp.Protocol) == 0 { - pp.Protocol = string(v1.ProtocolTCP) - } - - return pp -} - -// HostPortInfo stores mapping from ip to a set of ProtocolPort -type HostPortInfo map[string]map[ProtocolPort]struct{} - -// Add adds (ip, protocol, port) to HostPortInfo -func (h HostPortInfo) Add(ip, protocol string, port int32) { - if port <= 0 { - return - } - - h.sanitize(&ip, &protocol) - - pp := NewProtocolPort(protocol, port) - if _, ok := h[ip]; !ok { - h[ip] = map[ProtocolPort]struct{}{ - *pp: {}, - } - return - } - - h[ip][*pp] = struct{}{} -} - -// Remove removes (ip, protocol, port) from HostPortInfo -func (h HostPortInfo) Remove(ip, protocol string, port int32) { - if port <= 0 { - return - } - - h.sanitize(&ip, &protocol) - - pp := NewProtocolPort(protocol, port) - if m, ok := h[ip]; ok { - delete(m, *pp) - if len(h[ip]) == 0 { - delete(h, ip) - } - } -} - -// Len returns the total number of (ip, protocol, port) tuple in HostPortInfo -func (h HostPortInfo) Len() int { - length := 0 - for _, m := range h { - length += len(m) - } - return length -} - -// CheckConflict checks if the input (ip, protocol, port) conflicts with the existing -// ones in HostPortInfo. -func (h HostPortInfo) CheckConflict(ip, protocol string, port int32) bool { - if port <= 0 { - return false - } - - h.sanitize(&ip, &protocol) - - pp := NewProtocolPort(protocol, port) - - // If ip is 0.0.0.0 check all IP's (protocol, port) pair - if ip == DefaultBindAllHostIP { - for _, m := range h { - if _, ok := m[*pp]; ok { - return true - } - } - return false - } - - // If ip isn't 0.0.0.0, only check IP and 0.0.0.0's (protocol, port) pair - for _, key := range []string{DefaultBindAllHostIP, ip} { - if m, ok := h[key]; ok { - if _, ok2 := m[*pp]; ok2 { - return true - } - } - } - - return false -} - -// sanitize the parameters -func (h HostPortInfo) sanitize(ip, protocol *string) { - if len(*ip) == 0 { - *ip = DefaultBindAllHostIP - } - if len(*protocol) == 0 { - *protocol = string(v1.ProtocolTCP) - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go deleted file mode 100644 index f59ea1e96..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metric_recorder.go +++ /dev/null @@ -1,224 +0,0 @@ -/* -Copyright 2019 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package metrics - -import ( - "time" - - "k8s.io/component-base/metrics" -) - -// MetricRecorder represents a metric recorder which takes action when the -// metric Inc(), Dec() and Clear() -type MetricRecorder interface { - Inc() - Dec() - Clear() -} - -var _ MetricRecorder = &PendingPodsRecorder{} - -// PendingPodsRecorder is an implementation of MetricRecorder -type PendingPodsRecorder struct { - recorder metrics.GaugeMetric -} - -// NewActivePodsRecorder returns ActivePods in a Prometheus metric fashion -func NewActivePodsRecorder() *PendingPodsRecorder { - return &PendingPodsRecorder{ - recorder: ActivePods(), - } -} - -// NewUnschedulablePodsRecorder returns UnschedulablePods in a Prometheus metric fashion -func NewUnschedulablePodsRecorder() *PendingPodsRecorder { - return &PendingPodsRecorder{ - recorder: UnschedulablePods(), - } -} - -// NewBackoffPodsRecorder returns BackoffPods in a Prometheus metric fashion -func NewBackoffPodsRecorder() *PendingPodsRecorder { - return &PendingPodsRecorder{ - recorder: BackoffPods(), - } -} - -// NewGatedPodsRecorder returns GatedPods in a Prometheus metric fashion -func NewGatedPodsRecorder() *PendingPodsRecorder { - return &PendingPodsRecorder{ - recorder: GatedPods(), - } -} - -// Inc increases a metric counter by 1, in an atomic way -func (r *PendingPodsRecorder) Inc() { - r.recorder.Inc() -} - -// Dec decreases a metric counter by 1, in an atomic way -func (r *PendingPodsRecorder) Dec() { - r.recorder.Dec() -} - -// Clear set a metric counter to 0, in an atomic way -func (r *PendingPodsRecorder) Clear() { - r.recorder.Set(float64(0)) -} - -// histogramVecMetric is the data structure passed in the buffer channel between the main framework thread -// and the metricsRecorder goroutine. -type histogramVecMetric struct { - metric *metrics.HistogramVec - labelValues []string - value float64 -} - -type gaugeVecMetric struct { - metric *metrics.GaugeVec - labelValues []string - valueToAdd float64 -} - -type gaugeVecMetricKey struct { - metricName string - labelValue string -} - -// MetricAsyncRecorder records metric in a separate goroutine to avoid overhead in the critical path. -type MetricAsyncRecorder struct { - // bufferCh is a channel that serves as a metrics buffer before the metricsRecorder goroutine reports it. - bufferCh chan *histogramVecMetric - // if bufferSize is reached, incoming metrics will be discarded. - bufferSize int - // how often the recorder runs to flush the metrics. - interval time.Duration - - // aggregatedInflightEventMetric is only to record InFlightEvents metric asynchronously. - // It's a map from gaugeVecMetricKey to the aggregated value - // and the aggregated value is flushed to Prometheus every time the interval is reached. - // Note that we don't lock the map deliberately because we assume the queue takes lock before updating the in-flight events. - aggregatedInflightEventMetric map[gaugeVecMetricKey]int - aggregatedInflightEventMetricLastFlushTime time.Time - aggregatedInflightEventMetricBufferCh chan *gaugeVecMetric - - // stopCh is used to stop the goroutine which periodically flushes metrics. - stopCh <-chan struct{} - // IsStoppedCh indicates whether the goroutine is stopped. It's used in tests only to make sure - // the metric flushing goroutine is stopped so that tests can collect metrics for verification. - IsStoppedCh chan struct{} -} - -func NewMetricsAsyncRecorder(bufferSize int, interval time.Duration, stopCh <-chan struct{}) *MetricAsyncRecorder { - recorder := &MetricAsyncRecorder{ - bufferCh: make(chan *histogramVecMetric, bufferSize), - bufferSize: bufferSize, - interval: interval, - stopCh: stopCh, - aggregatedInflightEventMetric: make(map[gaugeVecMetricKey]int), - aggregatedInflightEventMetricLastFlushTime: time.Now(), - aggregatedInflightEventMetricBufferCh: make(chan *gaugeVecMetric, bufferSize), - IsStoppedCh: make(chan struct{}), - } - go recorder.run() - return recorder -} - -// ObservePluginDurationAsync observes the plugin_execution_duration_seconds metric. -// The metric will be flushed to Prometheus asynchronously. -func (r *MetricAsyncRecorder) ObservePluginDurationAsync(extensionPoint, pluginName, status string, value float64) { - r.observeMetricAsync(PluginExecutionDuration, value, pluginName, extensionPoint, status) -} - -// ObserveQueueingHintDurationAsync observes the queueing_hint_execution_duration_seconds metric. -// The metric will be flushed to Prometheus asynchronously. -func (r *MetricAsyncRecorder) ObserveQueueingHintDurationAsync(pluginName, event, hint string, value float64) { - r.observeMetricAsync(queueingHintExecutionDuration, value, pluginName, event, hint) -} - -// ObserveInFlightEventsAsync observes the in_flight_events metric. -// -// Note that this function is not goroutine-safe; -// we don't lock the map deliberately for the performance reason and we assume the queue (i.e., the caller) takes lock before updating the in-flight events. -func (r *MetricAsyncRecorder) ObserveInFlightEventsAsync(eventLabel string, valueToAdd float64, forceFlush bool) { - r.aggregatedInflightEventMetric[gaugeVecMetricKey{metricName: InFlightEvents.Name, labelValue: eventLabel}] += int(valueToAdd) - - // Only flush the metric to the channel if the interval is reached. - // The values are flushed to Prometheus in the run() function, which runs once the interval time. - // Note: we implement this flushing here, not in FlushMetrics, because, if we did so, we would need to implement a lock for the map, which we want to avoid. - if forceFlush || time.Since(r.aggregatedInflightEventMetricLastFlushTime) > r.interval { - for key, value := range r.aggregatedInflightEventMetric { - newMetric := &gaugeVecMetric{ - metric: InFlightEvents, - labelValues: []string{key.labelValue}, - valueToAdd: float64(value), - } - select { - case r.aggregatedInflightEventMetricBufferCh <- newMetric: - default: - } - } - r.aggregatedInflightEventMetricLastFlushTime = time.Now() - // reset - r.aggregatedInflightEventMetric = make(map[gaugeVecMetricKey]int) - } -} - -func (r *MetricAsyncRecorder) observeMetricAsync(m *metrics.HistogramVec, value float64, labelsValues ...string) { - newMetric := &histogramVecMetric{ - metric: m, - labelValues: labelsValues, - value: value, - } - select { - case r.bufferCh <- newMetric: - default: - } -} - -// run flushes buffered metrics into Prometheus every second. -func (r *MetricAsyncRecorder) run() { - for { - select { - case <-r.stopCh: - close(r.IsStoppedCh) - return - default: - } - r.FlushMetrics() - time.Sleep(r.interval) - } -} - -// FlushMetrics tries to clean up the bufferCh by reading at most bufferSize metrics. -func (r *MetricAsyncRecorder) FlushMetrics() { - for i := 0; i < r.bufferSize; i++ { - select { - case m := <-r.bufferCh: - m.metric.WithLabelValues(m.labelValues...).Observe(m.value) - default: - // no more value - } - - select { - case m := <-r.aggregatedInflightEventMetricBufferCh: - m.metric.WithLabelValues(m.labelValues...).Add(m.valueToAdd) - default: - // no more value - } - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go deleted file mode 100644 index 3d0edacd9..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/metrics.go +++ /dev/null @@ -1,411 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package metrics - -import ( - "sync" - "time" - - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/component-base/metrics" - "k8s.io/component-base/metrics/legacyregistry" - "k8s.io/kubernetes/pkg/features" - volumebindingmetrics "k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics" -) - -const ( - // SchedulerSubsystem - subsystem name used by scheduler. - SchedulerSubsystem = "scheduler" -) - -// Below are possible values for the work and operation label. -const ( - // PrioritizingExtender - prioritizing extender work/operation label value. - PrioritizingExtender = "prioritizing_extender" - // Binding - binding work/operation label value. - Binding = "binding" -) - -const ( - GoroutineResultSuccess = "success" - GoroutineResultError = "error" -) - -// ExtentionPoints is a list of possible values for the extension_point label. -var ExtentionPoints = []string{ - PreFilter, - Filter, - PreFilterExtensionAddPod, - PreFilterExtensionRemovePod, - PostFilter, - PreScore, - Score, - ScoreExtensionNormalize, - PreBind, - Bind, - PostBind, - Reserve, - Unreserve, - Permit, -} - -const ( - PreFilter = "PreFilter" - Filter = "Filter" - PreFilterExtensionAddPod = "PreFilterExtensionAddPod" - PreFilterExtensionRemovePod = "PreFilterExtensionRemovePod" - PostFilter = "PostFilter" - PreScore = "PreScore" - Score = "Score" - ScoreExtensionNormalize = "ScoreExtensionNormalize" - PreBind = "PreBind" - Bind = "Bind" - PostBind = "PostBind" - Reserve = "Reserve" - Unreserve = "Unreserve" - Permit = "Permit" -) - -const ( - QueueingHintResultQueue = "Queue" - QueueingHintResultQueueSkip = "QueueSkip" - QueueingHintResultError = "Error" -) - -const ( - PodPoppedInFlightEvent = "PodPopped" -) - -// All the histogram based metrics have 1ms as size for the smallest bucket. -var ( - scheduleAttempts *metrics.CounterVec - EventHandlingLatency *metrics.HistogramVec - schedulingLatency *metrics.HistogramVec - SchedulingAlgorithmLatency *metrics.Histogram - PreemptionVictims *metrics.Histogram - PreemptionAttempts *metrics.Counter - pendingPods *metrics.GaugeVec - InFlightEvents *metrics.GaugeVec - Goroutines *metrics.GaugeVec - - PodSchedulingSLIDuration *metrics.HistogramVec - PodSchedulingAttempts *metrics.Histogram - FrameworkExtensionPointDuration *metrics.HistogramVec - PluginExecutionDuration *metrics.HistogramVec - - PermitWaitDuration *metrics.HistogramVec - CacheSize *metrics.GaugeVec - // Deprecated: SchedulerCacheSize is deprecated, - // and will be removed at v1.34. Please use CacheSize instead. - SchedulerCacheSize *metrics.GaugeVec - unschedulableReasons *metrics.GaugeVec - PluginEvaluationTotal *metrics.CounterVec - - // The below two are only available when the QHint feature gate is enabled. - queueingHintExecutionDuration *metrics.HistogramVec - SchedulerQueueIncomingPods *metrics.CounterVec - - // The below two are only available when the async-preemption feature gate is enabled. - PreemptionGoroutinesDuration *metrics.HistogramVec - PreemptionGoroutinesExecutionTotal *metrics.CounterVec - - // metricsList is a list of all metrics that should be registered always, regardless of any feature gate's value. - metricsList []metrics.Registerable -) - -var registerMetrics sync.Once - -// Register all metrics. -func Register() { - // Register the metrics. - registerMetrics.Do(func() { - InitMetrics() - RegisterMetrics(metricsList...) - volumebindingmetrics.RegisterVolumeSchedulingMetrics() - - if utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { - RegisterMetrics(queueingHintExecutionDuration, InFlightEvents) - } - if utilfeature.DefaultFeatureGate.Enabled(features.SchedulerAsyncPreemption) { - RegisterMetrics(PreemptionGoroutinesDuration, PreemptionGoroutinesExecutionTotal) - } - }) -} - -func InitMetrics() { - scheduleAttempts = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: SchedulerSubsystem, - Name: "schedule_attempts_total", - Help: "Number of attempts to schedule pods, by the result. 'unschedulable' means a pod could not be scheduled, while 'error' means an internal scheduler problem.", - StabilityLevel: metrics.STABLE, - }, []string{"result", "profile"}) - - EventHandlingLatency = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "event_handling_duration_seconds", - Help: "Event handling latency in seconds.", - // Start with 0.1ms with the last bucket being [~200ms, Inf) - Buckets: metrics.ExponentialBuckets(0.0001, 2, 12), - StabilityLevel: metrics.ALPHA, - }, []string{"event"}) - - schedulingLatency = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "scheduling_attempt_duration_seconds", - Help: "Scheduling attempt latency in seconds (scheduling algorithm + binding)", - Buckets: metrics.ExponentialBuckets(0.001, 2, 15), - StabilityLevel: metrics.STABLE, - }, []string{"result", "profile"}) - SchedulingAlgorithmLatency = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "scheduling_algorithm_duration_seconds", - Help: "Scheduling algorithm latency in seconds", - Buckets: metrics.ExponentialBuckets(0.001, 2, 15), - StabilityLevel: metrics.ALPHA, - }, - ) - PreemptionVictims = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "preemption_victims", - Help: "Number of selected preemption victims", - // we think #victims>64 is pretty rare, therefore [64, +Inf) is considered a single bucket. - Buckets: metrics.ExponentialBuckets(1, 2, 7), - StabilityLevel: metrics.STABLE, - }) - PreemptionAttempts = metrics.NewCounter( - &metrics.CounterOpts{ - Subsystem: SchedulerSubsystem, - Name: "preemption_attempts_total", - Help: "Total preemption attempts in the cluster till now", - StabilityLevel: metrics.STABLE, - }) - pendingPods = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: SchedulerSubsystem, - Name: "pending_pods", - Help: "Number of pending pods, by the queue type. 'active' means number of pods in activeQ; 'backoff' means number of pods in backoffQ; 'unschedulable' means number of pods in unschedulablePods that the scheduler attempted to schedule and failed; 'gated' is the number of unschedulable pods that the scheduler never attempted to schedule because they are gated.", - StabilityLevel: metrics.STABLE, - }, []string{"queue"}) - InFlightEvents = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: SchedulerSubsystem, - Name: "inflight_events", - Help: "Number of events currently tracked in the scheduling queue.", - StabilityLevel: metrics.ALPHA, - }, []string{"event"}) - Goroutines = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: SchedulerSubsystem, - Name: "goroutines", - Help: "Number of running goroutines split by the work they do such as binding.", - StabilityLevel: metrics.ALPHA, - }, []string{"operation"}) - - PodSchedulingSLIDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "pod_scheduling_sli_duration_seconds", - Help: "E2e latency for a pod being scheduled, from the time the pod enters the scheduling queue and might involve multiple scheduling attempts.", - // Start with 10ms with the last bucket being [~88m, Inf). - Buckets: metrics.ExponentialBuckets(0.01, 2, 20), - StabilityLevel: metrics.BETA, - }, - []string{"attempts"}) - - PodSchedulingAttempts = metrics.NewHistogram( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "pod_scheduling_attempts", - Help: "Number of attempts to successfully schedule a pod.", - Buckets: metrics.ExponentialBuckets(1, 2, 5), - StabilityLevel: metrics.STABLE, - }) - - FrameworkExtensionPointDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "framework_extension_point_duration_seconds", - Help: "Latency for running all plugins of a specific extension point.", - // Start with 0.1ms with the last bucket being [~200ms, Inf) - Buckets: metrics.ExponentialBuckets(0.0001, 2, 12), - StabilityLevel: metrics.STABLE, - }, - []string{"extension_point", "status", "profile"}) - - PluginExecutionDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "plugin_execution_duration_seconds", - Help: "Duration for running a plugin at a specific extension point.", - // Start with 0.01ms with the last bucket being [~22ms, Inf). We use a small factor (1.5) - // so that we have better granularity since plugin latency is very sensitive. - Buckets: metrics.ExponentialBuckets(0.00001, 1.5, 20), - StabilityLevel: metrics.ALPHA, - }, - []string{"plugin", "extension_point", "status"}) - - // This is only available when the QHint feature gate is enabled. - queueingHintExecutionDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "queueing_hint_execution_duration_seconds", - Help: "Duration for running a queueing hint function of a plugin.", - // Start with 0.01ms with the last bucket being [~22ms, Inf). We use a small factor (1.5) - // so that we have better granularity since plugin latency is very sensitive. - Buckets: metrics.ExponentialBuckets(0.00001, 1.5, 20), - StabilityLevel: metrics.ALPHA, - }, - []string{"plugin", "event", "hint"}) - - SchedulerQueueIncomingPods = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: SchedulerSubsystem, - Name: "queue_incoming_pods_total", - Help: "Number of pods added to scheduling queues by event and queue type.", - StabilityLevel: metrics.STABLE, - }, []string{"queue", "event"}) - - PermitWaitDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "permit_wait_duration_seconds", - Help: "Duration of waiting on permit.", - Buckets: metrics.ExponentialBuckets(0.001, 2, 15), - StabilityLevel: metrics.ALPHA, - }, - []string{"result"}) - - SchedulerCacheSize = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: SchedulerSubsystem, - Name: "scheduler_cache_size", - Help: "Number of nodes, pods, and assumed (bound) pods in the scheduler cache.", - StabilityLevel: metrics.ALPHA, - DeprecatedVersion: "1.33.0", - }, []string{"type"}) - - CacheSize = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: SchedulerSubsystem, - Name: "cache_size", - Help: "Number of nodes, pods, and assumed (bound) pods in the scheduler cache.", - StabilityLevel: metrics.ALPHA, - }, []string{"type"}) - - unschedulableReasons = metrics.NewGaugeVec( - &metrics.GaugeOpts{ - Subsystem: SchedulerSubsystem, - Name: "unschedulable_pods", - Help: "The number of unschedulable pods broken down by plugin name. A pod will increment the gauge for all plugins that caused it to not schedule and so this metric have meaning only when broken down by plugin.", - StabilityLevel: metrics.ALPHA, - }, []string{"plugin", "profile"}) - - PluginEvaluationTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: SchedulerSubsystem, - Name: "plugin_evaluation_total", - Help: "Number of attempts to schedule pods by each plugin and the extension point (available only in PreFilter, Filter, PreScore, and Score).", - StabilityLevel: metrics.ALPHA, - }, []string{"plugin", "extension_point", "profile"}) - - PreemptionGoroutinesDuration = metrics.NewHistogramVec( - &metrics.HistogramOpts{ - Subsystem: SchedulerSubsystem, - Name: "preemption_goroutines_duration_seconds", - Help: "Duration in seconds for running goroutines for the preemption.", - Buckets: metrics.ExponentialBuckets(0.01, 2, 20), - StabilityLevel: metrics.ALPHA, - }, - []string{"result"}) - - PreemptionGoroutinesExecutionTotal = metrics.NewCounterVec( - &metrics.CounterOpts{ - Subsystem: SchedulerSubsystem, - Name: "preemption_goroutines_execution_total", - Help: "Number of preemption goroutines executed.", - StabilityLevel: metrics.ALPHA, - }, - []string{"result"}) - - metricsList = []metrics.Registerable{ - scheduleAttempts, - schedulingLatency, - SchedulingAlgorithmLatency, - EventHandlingLatency, - PreemptionVictims, - PreemptionAttempts, - pendingPods, - PodSchedulingSLIDuration, - PodSchedulingAttempts, - FrameworkExtensionPointDuration, - PluginExecutionDuration, - SchedulerQueueIncomingPods, - Goroutines, - PermitWaitDuration, - CacheSize, - SchedulerCacheSize, - unschedulableReasons, - PluginEvaluationTotal, - } -} - -// RegisterMetrics registers a list of metrics. -// This function is exported because it is intended to be used by out-of-tree plugins to register their custom metrics. -func RegisterMetrics(extraMetrics ...metrics.Registerable) { - for _, metric := range extraMetrics { - legacyregistry.MustRegister(metric) - } -} - -// GetGather returns the gatherer. It used by test case outside current package. -func GetGather() metrics.Gatherer { - return legacyregistry.DefaultGatherer -} - -// ActivePods returns the pending pods metrics with the label active -func ActivePods() metrics.GaugeMetric { - return pendingPods.With(metrics.Labels{"queue": "active"}) -} - -// BackoffPods returns the pending pods metrics with the label backoff -func BackoffPods() metrics.GaugeMetric { - return pendingPods.With(metrics.Labels{"queue": "backoff"}) -} - -// UnschedulablePods returns the pending pods metrics with the label unschedulable -func UnschedulablePods() metrics.GaugeMetric { - return pendingPods.With(metrics.Labels{"queue": "unschedulable"}) -} - -// GatedPods returns the pending pods metrics with the label gated -func GatedPods() metrics.GaugeMetric { - return pendingPods.With(metrics.Labels{"queue": "gated"}) -} - -// SinceInSeconds gets the time since the specified start in seconds. -func SinceInSeconds(start time.Time) float64 { - return time.Since(start).Seconds() -} - -func UnschedulableReason(plugin string, profile string) metrics.GaugeMetric { - return unschedulableReasons.With(metrics.Labels{"plugin": plugin, "profile": profile}) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go b/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go deleted file mode 100644 index d8e36e9df..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/metrics/profile_metrics.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package metrics - -// This file contains helpers for metrics that are associated to a profile. - -var ( - ScheduledResult = "scheduled" - UnschedulableResult = "unschedulable" - ErrorResult = "error" -) - -// PodScheduled can records a successful scheduling attempt and the duration -// since `start`. -func PodScheduled(profile string, duration float64) { - observeScheduleAttemptAndLatency(ScheduledResult, profile, duration) -} - -// PodUnschedulable can records a scheduling attempt for an unschedulable pod -// and the duration since `start`. -func PodUnschedulable(profile string, duration float64) { - observeScheduleAttemptAndLatency(UnschedulableResult, profile, duration) -} - -// PodScheduleError can records a scheduling attempt that had an error and the -// duration since `start`. -func PodScheduleError(profile string, duration float64) { - observeScheduleAttemptAndLatency(ErrorResult, profile, duration) -} - -func observeScheduleAttemptAndLatency(result, profile string, duration float64) { - schedulingLatency.WithLabelValues(result, profile).Observe(duration) - scheduleAttempts.WithLabelValues(result, profile).Inc() -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go b/vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go deleted file mode 100644 index 9cd510d35..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/profile/profile.go +++ /dev/null @@ -1,130 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package profile holds the definition of a scheduling Profile. -package profile - -import ( - "context" - "errors" - "fmt" - - "github.com/google/go-cmp/cmp" //nolint:depguard - - "k8s.io/apimachinery/pkg/runtime" - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/tools/events" - "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/framework" - frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime" -) - -// RecorderFactory builds an EventRecorder for a given scheduler name. -type RecorderFactory func(string) events.EventRecorder - -// newProfile builds a Profile for the given configuration. -func newProfile(ctx context.Context, cfg config.KubeSchedulerProfile, r frameworkruntime.Registry, recorderFact RecorderFactory, - opts ...frameworkruntime.Option) (framework.Framework, error) { - recorder := recorderFact(cfg.SchedulerName) - opts = append(opts, frameworkruntime.WithEventRecorder(recorder)) - return frameworkruntime.NewFramework(ctx, r, &cfg, opts...) -} - -// Map holds frameworks indexed by scheduler name. -type Map map[string]framework.Framework - -// NewMap builds the frameworks given by the configuration, indexed by name. -func NewMap(ctx context.Context, cfgs []config.KubeSchedulerProfile, r frameworkruntime.Registry, recorderFact RecorderFactory, - opts ...frameworkruntime.Option) (Map, error) { - m := make(Map) - v := cfgValidator{m: m} - - for _, cfg := range cfgs { - p, err := newProfile(ctx, cfg, r, recorderFact, opts...) - if err != nil { - return nil, fmt.Errorf("creating profile for scheduler name %s: %v", cfg.SchedulerName, err) - } - if err := v.validate(cfg, p); err != nil { - return nil, err - } - m[cfg.SchedulerName] = p - } - return m, nil -} - -// HandlesSchedulerName returns whether a profile handles the given scheduler name. -func (m Map) HandlesSchedulerName(name string) bool { - _, ok := m[name] - return ok -} - -// Close closes all frameworks registered in this map. -func (m Map) Close() error { - var errs []error - for name, f := range m { - err := f.Close() - if err != nil { - errs = append(errs, fmt.Errorf("framework %s failed to close: %w", name, err)) - } - } - return errors.Join(errs...) -} - -// NewRecorderFactory returns a RecorderFactory for the broadcaster. -func NewRecorderFactory(b events.EventBroadcaster) RecorderFactory { - return func(name string) events.EventRecorder { - return b.NewRecorder(scheme.Scheme, name) - } -} - -type cfgValidator struct { - m Map - queueSort string - queueSortArgs runtime.Object -} - -func (v *cfgValidator) validate(cfg config.KubeSchedulerProfile, f framework.Framework) error { - if len(f.ProfileName()) == 0 { - return errors.New("scheduler name is needed") - } - if cfg.Plugins == nil { - return fmt.Errorf("plugins required for profile with scheduler name %q", f.ProfileName()) - } - if v.m[f.ProfileName()] != nil { - return fmt.Errorf("duplicate profile with scheduler name %q", f.ProfileName()) - } - - queueSort := f.ListPlugins().QueueSort.Enabled[0].Name - var queueSortArgs runtime.Object - for _, plCfg := range cfg.PluginConfig { - if plCfg.Name == queueSort { - queueSortArgs = plCfg.Args - break - } - } - if len(v.queueSort) == 0 { - v.queueSort = queueSort - v.queueSortArgs = queueSortArgs - return nil - } - if v.queueSort != queueSort { - return fmt.Errorf("different queue sort plugins for profile %q: %q, first: %q", cfg.SchedulerName, queueSort, v.queueSort) - } - if !cmp.Equal(v.queueSortArgs, queueSortArgs) { - return fmt.Errorf("different queue sort plugin args for profile %q", cfg.SchedulerName) - } - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go b/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go deleted file mode 100644 index 35b784922..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/schedule_one.go +++ /dev/null @@ -1,1123 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package scheduler - -import ( - "container/heap" - "context" - "errors" - "fmt" - "math/rand" - "strconv" - "sync" - "sync/atomic" - "time" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/apimachinery/pkg/util/sets" - clientset "k8s.io/client-go/kubernetes" - "k8s.io/klog/v2" - extenderv1 "k8s.io/kube-scheduler/extender/v1" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/pkg/apis/core/validation" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/scheduler/util" - utiltrace "k8s.io/utils/trace" -) - -const ( - // Percentage of plugin metrics to be sampled. - pluginMetricsSamplePercent = 10 - // minFeasibleNodesToFind is the minimum number of nodes that would be scored - // in each scheduling cycle. This is a semi-arbitrary value to ensure that a - // certain minimum of nodes are checked for feasibility. This in turn helps - // ensure a minimum level of spreading. - minFeasibleNodesToFind = 100 - // minFeasibleNodesPercentageToFind is the minimum percentage of nodes that - // would be scored in each scheduling cycle. This is a semi-arbitrary value - // to ensure that a certain minimum of nodes are checked for feasibility. - // This in turn helps ensure a minimum level of spreading. - minFeasibleNodesPercentageToFind = 5 - // numberOfHighestScoredNodesToReport is the number of node scores - // to be included in ScheduleResult. - numberOfHighestScoredNodesToReport = 3 -) - -// ScheduleOne does the entire scheduling workflow for a single pod. It is serialized on the scheduling algorithm's host fitting. -func (sched *Scheduler) ScheduleOne(ctx context.Context) { - logger := klog.FromContext(ctx) - podInfo, err := sched.NextPod(logger) - if err != nil { - logger.Error(err, "Error while retrieving next pod from scheduling queue") - return - } - // pod could be nil when schedulerQueue is closed - if podInfo == nil || podInfo.Pod == nil { - return - } - - pod := podInfo.Pod - // TODO(knelasevero): Remove duplicated keys from log entry calls - // When contextualized logging hits GA - // https://github.com/kubernetes/kubernetes/issues/111672 - logger = klog.LoggerWithValues(logger, "pod", klog.KObj(pod)) - ctx = klog.NewContext(ctx, logger) - logger.V(4).Info("About to try and schedule pod", "pod", klog.KObj(pod)) - - fwk, err := sched.frameworkForPod(pod) - if err != nil { - // This shouldn't happen, because we only accept for scheduling the pods - // which specify a scheduler name that matches one of the profiles. - logger.Error(err, "Error occurred") - sched.SchedulingQueue.Done(pod.UID) - return - } - if sched.skipPodSchedule(ctx, fwk, pod) { - // We don't put this Pod back to the queue, but we have to cleanup the in-flight pods/events. - sched.SchedulingQueue.Done(pod.UID) - return - } - - logger.V(3).Info("Attempting to schedule pod", "pod", klog.KObj(pod)) - - // Synchronously attempt to find a fit for the pod. - start := time.Now() - state := framework.NewCycleState() - state.SetRecordPluginMetrics(rand.Intn(100) < pluginMetricsSamplePercent) - - // Initialize an empty podsToActivate struct, which will be filled up by plugins or stay empty. - podsToActivate := framework.NewPodsToActivate() - state.Write(framework.PodsToActivateKey, podsToActivate) - - schedulingCycleCtx, cancel := context.WithCancel(ctx) - defer cancel() - - scheduleResult, assumedPodInfo, status := sched.schedulingCycle(schedulingCycleCtx, state, fwk, podInfo, start, podsToActivate) - if !status.IsSuccess() { - sched.FailureHandler(schedulingCycleCtx, fwk, assumedPodInfo, status, scheduleResult.nominatingInfo, start) - return - } - - // bind the pod to its host asynchronously (we can do this b/c of the assumption step above). - go func() { - bindingCycleCtx, cancel := context.WithCancel(ctx) - defer cancel() - - metrics.Goroutines.WithLabelValues(metrics.Binding).Inc() - defer metrics.Goroutines.WithLabelValues(metrics.Binding).Dec() - - status := sched.bindingCycle(bindingCycleCtx, state, fwk, scheduleResult, assumedPodInfo, start, podsToActivate) - if !status.IsSuccess() { - sched.handleBindingCycleError(bindingCycleCtx, state, fwk, assumedPodInfo, start, scheduleResult, status) - return - } - }() -} - -var clearNominatedNode = &framework.NominatingInfo{NominatingMode: framework.ModeOverride, NominatedNodeName: ""} - -// schedulingCycle tries to schedule a single Pod. -func (sched *Scheduler) schedulingCycle( - ctx context.Context, - state *framework.CycleState, - fwk framework.Framework, - podInfo *framework.QueuedPodInfo, - start time.Time, - podsToActivate *framework.PodsToActivate, -) (ScheduleResult, *framework.QueuedPodInfo, *framework.Status) { - logger := klog.FromContext(ctx) - pod := podInfo.Pod - scheduleResult, err := sched.SchedulePod(ctx, fwk, state, pod) - if err != nil { - defer func() { - metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInSeconds(start)) - }() - if err == ErrNoNodesAvailable { - status := framework.NewStatus(framework.UnschedulableAndUnresolvable).WithError(err) - return ScheduleResult{nominatingInfo: clearNominatedNode}, podInfo, status - } - - fitError, ok := err.(*framework.FitError) - if !ok { - logger.Error(err, "Error selecting node for pod", "pod", klog.KObj(pod)) - return ScheduleResult{nominatingInfo: clearNominatedNode}, podInfo, framework.AsStatus(err) - } - - // SchedulePod() may have failed because the pod would not fit on any host, so we try to - // preempt, with the expectation that the next time the pod is tried for scheduling it - // will fit due to the preemption. It is also possible that a different pod will schedule - // into the resources that were preempted, but this is harmless. - - if !fwk.HasPostFilterPlugins() { - logger.V(3).Info("No PostFilter plugins are registered, so no preemption will be performed") - return ScheduleResult{}, podInfo, framework.NewStatus(framework.Unschedulable).WithError(err) - } - - // Run PostFilter plugins to attempt to make the pod schedulable in a future scheduling cycle. - result, status := fwk.RunPostFilterPlugins(ctx, state, pod, fitError.Diagnosis.NodeToStatus) - msg := status.Message() - fitError.Diagnosis.PostFilterMsg = msg - if status.Code() == framework.Error { - logger.Error(nil, "Status after running PostFilter plugins for pod", "pod", klog.KObj(pod), "status", msg) - } else { - logger.V(5).Info("Status after running PostFilter plugins for pod", "pod", klog.KObj(pod), "status", msg) - } - - var nominatingInfo *framework.NominatingInfo - if result != nil { - nominatingInfo = result.NominatingInfo - } - return ScheduleResult{nominatingInfo: nominatingInfo}, podInfo, framework.NewStatus(framework.Unschedulable).WithError(err) - } - - metrics.SchedulingAlgorithmLatency.Observe(metrics.SinceInSeconds(start)) - // Tell the cache to assume that a pod now is running on a given node, even though it hasn't been bound yet. - // This allows us to keep scheduling without waiting on binding to occur. - assumedPodInfo := podInfo.DeepCopy() - assumedPod := assumedPodInfo.Pod - // assume modifies `assumedPod` by setting NodeName=scheduleResult.SuggestedHost - err = sched.assume(logger, assumedPod, scheduleResult.SuggestedHost) - if err != nil { - // This is most probably result of a BUG in retrying logic. - // We report an error here so that pod scheduling can be retried. - // This relies on the fact that Error will check if the pod has been bound - // to a node and if so will not add it back to the unscheduled pods queue - // (otherwise this would cause an infinite loop). - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, framework.AsStatus(err) - } - - // Run the Reserve method of reserve plugins. - if sts := fwk.RunReservePluginsReserve(ctx, state, assumedPod, scheduleResult.SuggestedHost); !sts.IsSuccess() { - // trigger un-reserve to clean up state associated with the reserved Pod - fwk.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if forgetErr := sched.Cache.ForgetPod(logger, assumedPod); forgetErr != nil { - logger.Error(forgetErr, "Scheduler cache ForgetPod failed") - } - - if sts.IsRejected() { - fitErr := &framework.FitError{ - NumAllNodes: 1, - Pod: pod, - Diagnosis: framework.Diagnosis{ - NodeToStatus: framework.NewDefaultNodeToStatus(), - }, - } - fitErr.Diagnosis.NodeToStatus.Set(scheduleResult.SuggestedHost, sts) - fitErr.Diagnosis.AddPluginStatus(sts) - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, framework.NewStatus(sts.Code()).WithError(fitErr) - } - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, sts - } - - // Run "permit" plugins. - runPermitStatus := fwk.RunPermitPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if !runPermitStatus.IsWait() && !runPermitStatus.IsSuccess() { - // trigger un-reserve to clean up state associated with the reserved Pod - fwk.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if forgetErr := sched.Cache.ForgetPod(logger, assumedPod); forgetErr != nil { - logger.Error(forgetErr, "Scheduler cache ForgetPod failed") - } - - if runPermitStatus.IsRejected() { - fitErr := &framework.FitError{ - NumAllNodes: 1, - Pod: pod, - Diagnosis: framework.Diagnosis{ - NodeToStatus: framework.NewDefaultNodeToStatus(), - }, - } - fitErr.Diagnosis.NodeToStatus.Set(scheduleResult.SuggestedHost, runPermitStatus) - fitErr.Diagnosis.AddPluginStatus(runPermitStatus) - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, framework.NewStatus(runPermitStatus.Code()).WithError(fitErr) - } - - return ScheduleResult{nominatingInfo: clearNominatedNode}, assumedPodInfo, runPermitStatus - } - - // At the end of a successful scheduling cycle, pop and move up Pods if needed. - if len(podsToActivate.Map) != 0 { - sched.SchedulingQueue.Activate(logger, podsToActivate.Map) - // Clear the entries after activation. - podsToActivate.Map = make(map[string]*v1.Pod) - } - - return scheduleResult, assumedPodInfo, nil -} - -// bindingCycle tries to bind an assumed Pod. -func (sched *Scheduler) bindingCycle( - ctx context.Context, - state *framework.CycleState, - fwk framework.Framework, - scheduleResult ScheduleResult, - assumedPodInfo *framework.QueuedPodInfo, - start time.Time, - podsToActivate *framework.PodsToActivate) *framework.Status { - logger := klog.FromContext(ctx) - - assumedPod := assumedPodInfo.Pod - - // Run "permit" plugins. - if status := fwk.WaitOnPermit(ctx, assumedPod); !status.IsSuccess() { - if status.IsRejected() { - fitErr := &framework.FitError{ - NumAllNodes: 1, - Pod: assumedPodInfo.Pod, - Diagnosis: framework.Diagnosis{ - NodeToStatus: framework.NewDefaultNodeToStatus(), - UnschedulablePlugins: sets.New(status.Plugin()), - }, - } - fitErr.Diagnosis.NodeToStatus.Set(scheduleResult.SuggestedHost, status) - return framework.NewStatus(status.Code()).WithError(fitErr) - } - return status - } - - // Any failures after this point cannot lead to the Pod being considered unschedulable. - // We define the Pod as "unschedulable" only when Pods are rejected at specific extension points, and Permit is the last one in the scheduling/binding cycle. - // If a Pod fails on PreBind or Bind, it should be moved to BackoffQ for retry. - // - // We can call Done() here because - // we can free the cluster events stored in the scheduling queue sooner, which is worth for busy clusters memory consumption wise. - sched.SchedulingQueue.Done(assumedPod.UID) - - // Run "prebind" plugins. - if status := fwk.RunPreBindPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost); !status.IsSuccess() { - return status - } - - // Run "bind" plugins. - if status := sched.bind(ctx, fwk, assumedPod, scheduleResult.SuggestedHost, state); !status.IsSuccess() { - return status - } - - // Calculating nodeResourceString can be heavy. Avoid it if klog verbosity is below 2. - logger.V(2).Info("Successfully bound pod to node", "pod", klog.KObj(assumedPod), "node", scheduleResult.SuggestedHost, "evaluatedNodes", scheduleResult.EvaluatedNodes, "feasibleNodes", scheduleResult.FeasibleNodes) - metrics.PodScheduled(fwk.ProfileName(), metrics.SinceInSeconds(start)) - metrics.PodSchedulingAttempts.Observe(float64(assumedPodInfo.Attempts)) - if assumedPodInfo.InitialAttemptTimestamp != nil { - metrics.PodSchedulingSLIDuration.WithLabelValues(getAttemptsLabel(assumedPodInfo)).Observe(metrics.SinceInSeconds(*assumedPodInfo.InitialAttemptTimestamp)) - } - // Run "postbind" plugins. - fwk.RunPostBindPlugins(ctx, state, assumedPod, scheduleResult.SuggestedHost) - - // At the end of a successful binding cycle, move up Pods if needed. - if len(podsToActivate.Map) != 0 { - sched.SchedulingQueue.Activate(logger, podsToActivate.Map) - // Unlike the logic in schedulingCycle(), we don't bother deleting the entries - // as `podsToActivate.Map` is no longer consumed. - } - - return nil -} - -func (sched *Scheduler) handleBindingCycleError( - ctx context.Context, - state *framework.CycleState, - fwk framework.Framework, - podInfo *framework.QueuedPodInfo, - start time.Time, - scheduleResult ScheduleResult, - status *framework.Status) { - logger := klog.FromContext(ctx) - - assumedPod := podInfo.Pod - // trigger un-reserve plugins to clean up state associated with the reserved Pod - fwk.RunReservePluginsUnreserve(ctx, state, assumedPod, scheduleResult.SuggestedHost) - if forgetErr := sched.Cache.ForgetPod(logger, assumedPod); forgetErr != nil { - logger.Error(forgetErr, "scheduler cache ForgetPod failed") - } else { - // "Forget"ing an assumed Pod in binding cycle should be treated as a PodDelete event, - // as the assumed Pod had occupied a certain amount of resources in scheduler cache. - // - // Avoid moving the assumed Pod itself as it's always Unschedulable. - // It's intentional to "defer" this operation; otherwise MoveAllToActiveOrBackoffQueue() would - // add this event to in-flight events and thus move the assumed pod to backoffQ anyways if the plugins don't have appropriate QueueingHint. - if status.IsRejected() { - defer sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventAssignedPodDelete, assumedPod, nil, func(pod *v1.Pod) bool { - return assumedPod.UID != pod.UID - }) - } else { - sched.SchedulingQueue.MoveAllToActiveOrBackoffQueue(logger, framework.EventAssignedPodDelete, assumedPod, nil, nil) - } - } - - sched.FailureHandler(ctx, fwk, podInfo, status, clearNominatedNode, start) -} - -func (sched *Scheduler) frameworkForPod(pod *v1.Pod) (framework.Framework, error) { - fwk, ok := sched.Profiles[pod.Spec.SchedulerName] - if !ok { - return nil, fmt.Errorf("profile not found for scheduler name %q", pod.Spec.SchedulerName) - } - return fwk, nil -} - -// skipPodSchedule returns true if we could skip scheduling the pod for specified cases. -func (sched *Scheduler) skipPodSchedule(ctx context.Context, fwk framework.Framework, pod *v1.Pod) bool { - // Case 1: pod is being deleted. - if pod.DeletionTimestamp != nil { - fwk.EventRecorder().Eventf(pod, nil, v1.EventTypeWarning, "FailedScheduling", "Scheduling", "skip schedule deleting pod: %v/%v", pod.Namespace, pod.Name) - klog.FromContext(ctx).V(3).Info("Skip schedule deleting pod", "pod", klog.KObj(pod)) - return true - } - - // Case 2: pod that has been assumed could be skipped. - // An assumed pod can be added again to the scheduling queue if it got an update event - // during its previous scheduling cycle but before getting assumed. - isAssumed, err := sched.Cache.IsAssumedPod(pod) - if err != nil { - // TODO(91633): pass ctx into a revised HandleError - utilruntime.HandleError(fmt.Errorf("failed to check whether pod %s/%s is assumed: %v", pod.Namespace, pod.Name, err)) - return false - } - return isAssumed -} - -// schedulePod tries to schedule the given pod to one of the nodes in the node list. -// If it succeeds, it will return the name of the node. -// If it fails, it will return a FitError with reasons. -func (sched *Scheduler) schedulePod(ctx context.Context, fwk framework.Framework, state *framework.CycleState, pod *v1.Pod) (result ScheduleResult, err error) { - trace := utiltrace.New("Scheduling", utiltrace.Field{Key: "namespace", Value: pod.Namespace}, utiltrace.Field{Key: "name", Value: pod.Name}) - defer trace.LogIfLong(100 * time.Millisecond) - if err := sched.Cache.UpdateSnapshot(klog.FromContext(ctx), sched.nodeInfoSnapshot); err != nil { - return result, err - } - trace.Step("Snapshotting scheduler cache and node infos done") - - if sched.nodeInfoSnapshot.NumNodes() == 0 { - return result, ErrNoNodesAvailable - } - - feasibleNodes, diagnosis, err := sched.findNodesThatFitPod(ctx, fwk, state, pod) - if err != nil { - return result, err - } - trace.Step("Computing predicates done") - - if len(feasibleNodes) == 0 { - return result, &framework.FitError{ - Pod: pod, - NumAllNodes: sched.nodeInfoSnapshot.NumNodes(), - Diagnosis: diagnosis, - } - } - - // When only one node after predicate, just use it. - if len(feasibleNodes) == 1 { - return ScheduleResult{ - SuggestedHost: feasibleNodes[0].Node().Name, - EvaluatedNodes: 1 + diagnosis.NodeToStatus.Len(), - FeasibleNodes: 1, - }, nil - } - - priorityList, err := prioritizeNodes(ctx, sched.Extenders, fwk, state, pod, feasibleNodes) - if err != nil { - return result, err - } - - host, _, err := selectHost(priorityList, numberOfHighestScoredNodesToReport) - trace.Step("Prioritizing done") - - return ScheduleResult{ - SuggestedHost: host, - EvaluatedNodes: len(feasibleNodes) + diagnosis.NodeToStatus.Len(), - FeasibleNodes: len(feasibleNodes), - }, err -} - -// Filters the nodes to find the ones that fit the pod based on the framework -// filter plugins and filter extenders. -func (sched *Scheduler) findNodesThatFitPod(ctx context.Context, fwk framework.Framework, state *framework.CycleState, pod *v1.Pod) ([]*framework.NodeInfo, framework.Diagnosis, error) { - logger := klog.FromContext(ctx) - diagnosis := framework.Diagnosis{ - NodeToStatus: framework.NewDefaultNodeToStatus(), - } - - allNodes, err := sched.nodeInfoSnapshot.NodeInfos().List() - if err != nil { - return nil, diagnosis, err - } - // Run "prefilter" plugins. - preRes, s, unscheduledPlugins := fwk.RunPreFilterPlugins(ctx, state, pod) - diagnosis.UnschedulablePlugins = unscheduledPlugins - if !s.IsSuccess() { - if !s.IsRejected() { - return nil, diagnosis, s.AsError() - } - // All nodes in NodeToStatus will have the same status so that they can be handled in the preemption. - diagnosis.NodeToStatus.SetAbsentNodesStatus(s) - - // Record the messages from PreFilter in Diagnosis.PreFilterMsg. - msg := s.Message() - diagnosis.PreFilterMsg = msg - logger.V(5).Info("Status after running PreFilter plugins for pod", "pod", klog.KObj(pod), "status", msg) - diagnosis.AddPluginStatus(s) - return nil, diagnosis, nil - } - - // "NominatedNodeName" can potentially be set in a previous scheduling cycle as a result of preemption. - // This node is likely the only candidate that will fit the pod, and hence we try it first before iterating over all nodes. - if len(pod.Status.NominatedNodeName) > 0 { - feasibleNodes, err := sched.evaluateNominatedNode(ctx, pod, fwk, state, diagnosis) - if err != nil { - logger.Error(err, "Evaluation failed on nominated node", "pod", klog.KObj(pod), "node", pod.Status.NominatedNodeName) - } - // Nominated node passes all the filters, scheduler is good to assign this node to the pod. - if len(feasibleNodes) != 0 { - return feasibleNodes, diagnosis, nil - } - } - - nodes := allNodes - if !preRes.AllNodes() { - nodes = make([]*framework.NodeInfo, 0, len(preRes.NodeNames)) - for nodeName := range preRes.NodeNames { - // PreRes may return nodeName(s) which do not exist; we verify - // node exists in the Snapshot. - if nodeInfo, err := sched.nodeInfoSnapshot.Get(nodeName); err == nil { - nodes = append(nodes, nodeInfo) - } - } - diagnosis.NodeToStatus.SetAbsentNodesStatus(framework.NewStatus(framework.UnschedulableAndUnresolvable, fmt.Sprintf("node(s) didn't satisfy plugin(s) %v", sets.List(unscheduledPlugins)))) - } - feasibleNodes, err := sched.findNodesThatPassFilters(ctx, fwk, state, pod, &diagnosis, nodes) - // always try to update the sched.nextStartNodeIndex regardless of whether an error has occurred - // this is helpful to make sure that all the nodes have a chance to be searched - processedNodes := len(feasibleNodes) + diagnosis.NodeToStatus.Len() - sched.nextStartNodeIndex = (sched.nextStartNodeIndex + processedNodes) % len(allNodes) - if err != nil { - return nil, diagnosis, err - } - - feasibleNodesAfterExtender, err := findNodesThatPassExtenders(ctx, sched.Extenders, pod, feasibleNodes, diagnosis.NodeToStatus) - if err != nil { - return nil, diagnosis, err - } - if len(feasibleNodesAfterExtender) != len(feasibleNodes) { - // Extenders filtered out some nodes. - // - // Extender doesn't support any kind of requeueing feature like EnqueueExtensions in the scheduling framework. - // When Extenders reject some Nodes and the pod ends up being unschedulable, - // we put framework.ExtenderName to pInfo.UnschedulablePlugins. - // This Pod will be requeued from unschedulable pod pool to activeQ/backoffQ - // by any kind of cluster events. - // https://github.com/kubernetes/kubernetes/issues/122019 - if diagnosis.UnschedulablePlugins == nil { - diagnosis.UnschedulablePlugins = sets.New[string]() - } - diagnosis.UnschedulablePlugins.Insert(framework.ExtenderName) - } - - return feasibleNodesAfterExtender, diagnosis, nil -} - -func (sched *Scheduler) evaluateNominatedNode(ctx context.Context, pod *v1.Pod, fwk framework.Framework, state *framework.CycleState, diagnosis framework.Diagnosis) ([]*framework.NodeInfo, error) { - nnn := pod.Status.NominatedNodeName - nodeInfo, err := sched.nodeInfoSnapshot.Get(nnn) - if err != nil { - return nil, err - } - node := []*framework.NodeInfo{nodeInfo} - feasibleNodes, err := sched.findNodesThatPassFilters(ctx, fwk, state, pod, &diagnosis, node) - if err != nil { - return nil, err - } - - feasibleNodes, err = findNodesThatPassExtenders(ctx, sched.Extenders, pod, feasibleNodes, diagnosis.NodeToStatus) - if err != nil { - return nil, err - } - - return feasibleNodes, nil -} - -// hasScoring checks if scoring nodes is configured. -func (sched *Scheduler) hasScoring(fwk framework.Framework) bool { - if fwk.HasScorePlugins() { - return true - } - for _, extender := range sched.Extenders { - if extender.IsPrioritizer() { - return true - } - } - return false -} - -// hasExtenderFilters checks if any extenders filter nodes. -func (sched *Scheduler) hasExtenderFilters() bool { - for _, extender := range sched.Extenders { - if extender.IsFilter() { - return true - } - } - return false -} - -// findNodesThatPassFilters finds the nodes that fit the filter plugins. -func (sched *Scheduler) findNodesThatPassFilters( - ctx context.Context, - fwk framework.Framework, - state *framework.CycleState, - pod *v1.Pod, - diagnosis *framework.Diagnosis, - nodes []*framework.NodeInfo) ([]*framework.NodeInfo, error) { - numAllNodes := len(nodes) - numNodesToFind := sched.numFeasibleNodesToFind(fwk.PercentageOfNodesToScore(), int32(numAllNodes)) - if !sched.hasExtenderFilters() && !sched.hasScoring(fwk) { - numNodesToFind = 1 - } - - // Create feasible list with enough space to avoid growing it - // and allow assigning. - feasibleNodes := make([]*framework.NodeInfo, numNodesToFind) - - if !fwk.HasFilterPlugins() { - for i := range feasibleNodes { - feasibleNodes[i] = nodes[(sched.nextStartNodeIndex+i)%numAllNodes] - } - return feasibleNodes, nil - } - - errCh := parallelize.NewErrorChannel() - var feasibleNodesLen int32 - ctx, cancel := context.WithCancel(ctx) - defer cancel() - - type nodeStatus struct { - node string - status *framework.Status - } - result := make([]*nodeStatus, numAllNodes) - checkNode := func(i int) { - // We check the nodes starting from where we left off in the previous scheduling cycle, - // this is to make sure all nodes have the same chance of being examined across pods. - nodeInfo := nodes[(sched.nextStartNodeIndex+i)%numAllNodes] - status := fwk.RunFilterPluginsWithNominatedPods(ctx, state, pod, nodeInfo) - if status.Code() == framework.Error { - errCh.SendErrorWithCancel(status.AsError(), cancel) - return - } - if status.IsSuccess() { - length := atomic.AddInt32(&feasibleNodesLen, 1) - if length > numNodesToFind { - cancel() - atomic.AddInt32(&feasibleNodesLen, -1) - } else { - feasibleNodes[length-1] = nodeInfo - } - } else { - result[i] = &nodeStatus{node: nodeInfo.Node().Name, status: status} - } - } - - beginCheckNode := time.Now() - statusCode := framework.Success - defer func() { - // We record Filter extension point latency here instead of in framework.go because framework.RunFilterPlugins - // function is called for each node, whereas we want to have an overall latency for all nodes per scheduling cycle. - // Note that this latency also includes latency for `addNominatedPods`, which calls framework.RunPreFilterAddPod. - metrics.FrameworkExtensionPointDuration.WithLabelValues(metrics.Filter, statusCode.String(), fwk.ProfileName()).Observe(metrics.SinceInSeconds(beginCheckNode)) - }() - - // Stops searching for more nodes once the configured number of feasible nodes - // are found. - fwk.Parallelizer().Until(ctx, numAllNodes, checkNode, metrics.Filter) - feasibleNodes = feasibleNodes[:feasibleNodesLen] - for _, item := range result { - if item == nil { - continue - } - diagnosis.NodeToStatus.Set(item.node, item.status) - diagnosis.AddPluginStatus(item.status) - } - if err := errCh.ReceiveError(); err != nil { - statusCode = framework.Error - return feasibleNodes, err - } - return feasibleNodes, nil -} - -// numFeasibleNodesToFind returns the number of feasible nodes that once found, the scheduler stops -// its search for more feasible nodes. -func (sched *Scheduler) numFeasibleNodesToFind(percentageOfNodesToScore *int32, numAllNodes int32) (numNodes int32) { - if numAllNodes < minFeasibleNodesToFind { - return numAllNodes - } - - // Use profile percentageOfNodesToScore if it's set. Otherwise, use global percentageOfNodesToScore. - var percentage int32 - if percentageOfNodesToScore != nil { - percentage = *percentageOfNodesToScore - } else { - percentage = sched.percentageOfNodesToScore - } - - if percentage == 0 { - percentage = int32(50) - numAllNodes/125 - if percentage < minFeasibleNodesPercentageToFind { - percentage = minFeasibleNodesPercentageToFind - } - } - - numNodes = numAllNodes * percentage / 100 - if numNodes < minFeasibleNodesToFind { - return minFeasibleNodesToFind - } - - return numNodes -} - -func findNodesThatPassExtenders(ctx context.Context, extenders []framework.Extender, pod *v1.Pod, feasibleNodes []*framework.NodeInfo, statuses *framework.NodeToStatus) ([]*framework.NodeInfo, error) { - logger := klog.FromContext(ctx) - - // Extenders are called sequentially. - // Nodes in original feasibleNodes can be excluded in one extender, and pass on to the next - // extender in a decreasing manner. - for _, extender := range extenders { - if len(feasibleNodes) == 0 { - break - } - if !extender.IsInterested(pod) { - continue - } - - // Status of failed nodes in failedAndUnresolvableMap will be added to , - // so that the scheduler framework can respect the UnschedulableAndUnresolvable status for - // particular nodes, and this may eventually improve preemption efficiency. - // Note: users are recommended to configure the extenders that may return UnschedulableAndUnresolvable - // status ahead of others. - feasibleList, failedMap, failedAndUnresolvableMap, err := extender.Filter(pod, feasibleNodes) - if err != nil { - if extender.IsIgnorable() { - logger.Info("Skipping extender as it returned error and has ignorable flag set", "extender", extender, "err", err) - continue - } - return nil, err - } - - for failedNodeName, failedMsg := range failedAndUnresolvableMap { - statuses.Set(failedNodeName, framework.NewStatus(framework.UnschedulableAndUnresolvable, failedMsg)) - } - - for failedNodeName, failedMsg := range failedMap { - if _, found := failedAndUnresolvableMap[failedNodeName]; found { - // failedAndUnresolvableMap takes precedence over failedMap - // note that this only happens if the extender returns the node in both maps - continue - } - statuses.Set(failedNodeName, framework.NewStatus(framework.Unschedulable, failedMsg)) - } - - feasibleNodes = feasibleList - } - return feasibleNodes, nil -} - -// prioritizeNodes prioritizes the nodes by running the score plugins, -// which return a score for each node from the call to RunScorePlugins(). -// The scores from each plugin are added together to make the score for that node, then -// any extenders are run as well. -// All scores are finally combined (added) to get the total weighted scores of all nodes -func prioritizeNodes( - ctx context.Context, - extenders []framework.Extender, - fwk framework.Framework, - state *framework.CycleState, - pod *v1.Pod, - nodes []*framework.NodeInfo, -) ([]framework.NodePluginScores, error) { - logger := klog.FromContext(ctx) - // If no priority configs are provided, then all nodes will have a score of one. - // This is required to generate the priority list in the required format - if len(extenders) == 0 && !fwk.HasScorePlugins() { - result := make([]framework.NodePluginScores, 0, len(nodes)) - for i := range nodes { - result = append(result, framework.NodePluginScores{ - Name: nodes[i].Node().Name, - TotalScore: 1, - }) - } - return result, nil - } - - // Run PreScore plugins. - preScoreStatus := fwk.RunPreScorePlugins(ctx, state, pod, nodes) - if !preScoreStatus.IsSuccess() { - return nil, preScoreStatus.AsError() - } - - // Run the Score plugins. - nodesScores, scoreStatus := fwk.RunScorePlugins(ctx, state, pod, nodes) - if !scoreStatus.IsSuccess() { - return nil, scoreStatus.AsError() - } - - // Additional details logged at level 10 if enabled. - loggerVTen := logger.V(10) - if loggerVTen.Enabled() { - for _, nodeScore := range nodesScores { - for _, pluginScore := range nodeScore.Scores { - loggerVTen.Info("Plugin scored node for pod", "pod", klog.KObj(pod), "plugin", pluginScore.Name, "node", nodeScore.Name, "score", pluginScore.Score) - } - } - } - - if len(extenders) != 0 && nodes != nil { - // allNodeExtendersScores has all extenders scores for all nodes. - // It is keyed with node name. - allNodeExtendersScores := make(map[string]*framework.NodePluginScores, len(nodes)) - var mu sync.Mutex - var wg sync.WaitGroup - for i := range extenders { - if !extenders[i].IsInterested(pod) { - continue - } - wg.Add(1) - go func(extIndex int) { - metrics.Goroutines.WithLabelValues(metrics.PrioritizingExtender).Inc() - defer func() { - metrics.Goroutines.WithLabelValues(metrics.PrioritizingExtender).Dec() - wg.Done() - }() - prioritizedList, weight, err := extenders[extIndex].Prioritize(pod, nodes) - if err != nil { - // Prioritization errors from extender can be ignored, let k8s/other extenders determine the priorities - logger.V(5).Info("Failed to run extender's priority function. No score given by this extender.", "error", err, "pod", klog.KObj(pod), "extender", extenders[extIndex].Name()) - return - } - mu.Lock() - defer mu.Unlock() - for i := range *prioritizedList { - nodename := (*prioritizedList)[i].Host - score := (*prioritizedList)[i].Score - if loggerVTen.Enabled() { - loggerVTen.Info("Extender scored node for pod", "pod", klog.KObj(pod), "extender", extenders[extIndex].Name(), "node", nodename, "score", score) - } - - // MaxExtenderPriority may diverge from the max priority used in the scheduler and defined by MaxNodeScore, - // therefore we need to scale the score returned by extenders to the score range used by the scheduler. - finalscore := score * weight * (framework.MaxNodeScore / extenderv1.MaxExtenderPriority) - - if allNodeExtendersScores[nodename] == nil { - allNodeExtendersScores[nodename] = &framework.NodePluginScores{ - Name: nodename, - Scores: make([]framework.PluginScore, 0, len(extenders)), - } - } - allNodeExtendersScores[nodename].Scores = append(allNodeExtendersScores[nodename].Scores, framework.PluginScore{ - Name: extenders[extIndex].Name(), - Score: finalscore, - }) - allNodeExtendersScores[nodename].TotalScore += finalscore - } - }(i) - } - // wait for all go routines to finish - wg.Wait() - for i := range nodesScores { - if score, ok := allNodeExtendersScores[nodes[i].Node().Name]; ok { - nodesScores[i].Scores = append(nodesScores[i].Scores, score.Scores...) - nodesScores[i].TotalScore += score.TotalScore - } - } - } - - if loggerVTen.Enabled() { - for i := range nodesScores { - loggerVTen.Info("Calculated node's final score for pod", "pod", klog.KObj(pod), "node", nodesScores[i].Name, "score", nodesScores[i].TotalScore) - } - } - return nodesScores, nil -} - -var errEmptyPriorityList = errors.New("empty priorityList") - -// selectHost takes a prioritized list of nodes and then picks one -// in a reservoir sampling manner from the nodes that had the highest score. -// It also returns the top {count} Nodes, -// and the top of the list will be always the selected host. -func selectHost(nodeScoreList []framework.NodePluginScores, count int) (string, []framework.NodePluginScores, error) { - if len(nodeScoreList) == 0 { - return "", nil, errEmptyPriorityList - } - - var h nodeScoreHeap = nodeScoreList - heap.Init(&h) - cntOfMaxScore := 1 - selectedIndex := 0 - // The top of the heap is the NodeScoreResult with the highest score. - sortedNodeScoreList := make([]framework.NodePluginScores, 0, count) - sortedNodeScoreList = append(sortedNodeScoreList, heap.Pop(&h).(framework.NodePluginScores)) - - // This for-loop will continue until all Nodes with the highest scores get checked for a reservoir sampling, - // and sortedNodeScoreList gets (count - 1) elements. - for ns := heap.Pop(&h).(framework.NodePluginScores); ; ns = heap.Pop(&h).(framework.NodePluginScores) { - if ns.TotalScore != sortedNodeScoreList[0].TotalScore && len(sortedNodeScoreList) == count { - break - } - - if ns.TotalScore == sortedNodeScoreList[0].TotalScore { - cntOfMaxScore++ - if rand.Intn(cntOfMaxScore) == 0 { - // Replace the candidate with probability of 1/cntOfMaxScore - selectedIndex = cntOfMaxScore - 1 - } - } - - sortedNodeScoreList = append(sortedNodeScoreList, ns) - - if h.Len() == 0 { - break - } - } - - if selectedIndex != 0 { - // replace the first one with selected one - previous := sortedNodeScoreList[0] - sortedNodeScoreList[0] = sortedNodeScoreList[selectedIndex] - sortedNodeScoreList[selectedIndex] = previous - } - - if len(sortedNodeScoreList) > count { - sortedNodeScoreList = sortedNodeScoreList[:count] - } - - return sortedNodeScoreList[0].Name, sortedNodeScoreList, nil -} - -// nodeScoreHeap is a heap of framework.NodePluginScores. -type nodeScoreHeap []framework.NodePluginScores - -// nodeScoreHeap implements heap.Interface. -var _ heap.Interface = &nodeScoreHeap{} - -func (h nodeScoreHeap) Len() int { return len(h) } -func (h nodeScoreHeap) Less(i, j int) bool { return h[i].TotalScore > h[j].TotalScore } -func (h nodeScoreHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } - -func (h *nodeScoreHeap) Push(x interface{}) { - *h = append(*h, x.(framework.NodePluginScores)) -} - -func (h *nodeScoreHeap) Pop() interface{} { - old := *h - n := len(old) - x := old[n-1] - *h = old[0 : n-1] - return x -} - -// assume signals to the cache that a pod is already in the cache, so that binding can be asynchronous. -// assume modifies `assumed`. -func (sched *Scheduler) assume(logger klog.Logger, assumed *v1.Pod, host string) error { - // Optimistically assume that the binding will succeed and send it to apiserver - // in the background. - // If the binding fails, scheduler will release resources allocated to assumed pod - // immediately. - assumed.Spec.NodeName = host - - if err := sched.Cache.AssumePod(logger, assumed); err != nil { - logger.Error(err, "Scheduler cache AssumePod failed") - return err - } - // if "assumed" is a nominated pod, we should remove it from internal cache - if sched.SchedulingQueue != nil { - sched.SchedulingQueue.DeleteNominatedPodIfExists(assumed) - } - - return nil -} - -// bind binds a pod to a given node defined in a binding object. -// The precedence for binding is: (1) extenders and (2) framework plugins. -// We expect this to run asynchronously, so we handle binding metrics internally. -func (sched *Scheduler) bind(ctx context.Context, fwk framework.Framework, assumed *v1.Pod, targetNode string, state *framework.CycleState) (status *framework.Status) { - logger := klog.FromContext(ctx) - defer func() { - sched.finishBinding(logger, fwk, assumed, targetNode, status) - }() - - bound, err := sched.extendersBinding(logger, assumed, targetNode) - if bound { - return framework.AsStatus(err) - } - return fwk.RunBindPlugins(ctx, state, assumed, targetNode) -} - -// TODO(#87159): Move this to a Plugin. -func (sched *Scheduler) extendersBinding(logger klog.Logger, pod *v1.Pod, node string) (bool, error) { - for _, extender := range sched.Extenders { - if !extender.IsBinder() || !extender.IsInterested(pod) { - continue - } - err := extender.Bind(&v1.Binding{ - ObjectMeta: metav1.ObjectMeta{Namespace: pod.Namespace, Name: pod.Name, UID: pod.UID}, - Target: v1.ObjectReference{Kind: "Node", Name: node}, - }) - if err != nil && extender.IsIgnorable() { - logger.Info("Skipping extender in bind as it returned error and has ignorable flag set", "extender", extender, "err", err) - continue - } - return true, err - } - return false, nil -} - -func (sched *Scheduler) finishBinding(logger klog.Logger, fwk framework.Framework, assumed *v1.Pod, targetNode string, status *framework.Status) { - if finErr := sched.Cache.FinishBinding(logger, assumed); finErr != nil { - logger.Error(finErr, "Scheduler cache FinishBinding failed") - } - if !status.IsSuccess() { - logger.V(1).Info("Failed to bind pod", "pod", klog.KObj(assumed)) - return - } - - fwk.EventRecorder().Eventf(assumed, nil, v1.EventTypeNormal, "Scheduled", "Binding", "Successfully assigned %v/%v to %v", assumed.Namespace, assumed.Name, targetNode) -} - -func getAttemptsLabel(p *framework.QueuedPodInfo) string { - // We breakdown the pod scheduling duration by attempts capped to a limit - // to avoid ending up with a high cardinality metric. - if p.Attempts >= 15 { - return "15+" - } - return strconv.Itoa(p.Attempts) -} - -// handleSchedulingFailure records an event for the pod that indicates the -// pod has failed to schedule. Also, update the pod condition and nominated node name if set. -func (sched *Scheduler) handleSchedulingFailure(ctx context.Context, fwk framework.Framework, podInfo *framework.QueuedPodInfo, status *framework.Status, nominatingInfo *framework.NominatingInfo, start time.Time) { - calledDone := false - defer func() { - if !calledDone { - // Basically, AddUnschedulableIfNotPresent calls DonePod internally. - // But, AddUnschedulableIfNotPresent isn't called in some corner cases. - // Here, we call DonePod explicitly to avoid leaking the pod. - sched.SchedulingQueue.Done(podInfo.Pod.UID) - } - }() - - logger := klog.FromContext(ctx) - reason := v1.PodReasonSchedulerError - if status.IsRejected() { - reason = v1.PodReasonUnschedulable - } - - switch reason { - case v1.PodReasonUnschedulable: - metrics.PodUnschedulable(fwk.ProfileName(), metrics.SinceInSeconds(start)) - case v1.PodReasonSchedulerError: - metrics.PodScheduleError(fwk.ProfileName(), metrics.SinceInSeconds(start)) - } - - pod := podInfo.Pod - err := status.AsError() - errMsg := status.Message() - - if err == ErrNoNodesAvailable { - logger.V(2).Info("Unable to schedule pod; no nodes are registered to the cluster; waiting", "pod", klog.KObj(pod)) - } else if fitError, ok := err.(*framework.FitError); ok { // Inject UnschedulablePlugins to PodInfo, which will be used later for moving Pods between queues efficiently. - podInfo.UnschedulablePlugins = fitError.Diagnosis.UnschedulablePlugins - podInfo.PendingPlugins = fitError.Diagnosis.PendingPlugins - logger.V(2).Info("Unable to schedule pod; no fit; waiting", "pod", klog.KObj(pod), "err", errMsg) - } else { - logger.Error(err, "Error scheduling pod; retrying", "pod", klog.KObj(pod)) - } - - // Check if the Pod exists in informer cache. - podLister := fwk.SharedInformerFactory().Core().V1().Pods().Lister() - cachedPod, e := podLister.Pods(pod.Namespace).Get(pod.Name) - if e != nil { - logger.Info("Pod doesn't exist in informer cache", "pod", klog.KObj(pod), "err", e) - // We need to call DonePod here because we don't call AddUnschedulableIfNotPresent in this case. - } else { - // In the case of extender, the pod may have been bound successfully, but timed out returning its response to the scheduler. - // It could result in the live version to carry .spec.nodeName, and that's inconsistent with the internal-queued version. - if len(cachedPod.Spec.NodeName) != 0 { - logger.Info("Pod has been assigned to node. Abort adding it back to queue.", "pod", klog.KObj(pod), "node", cachedPod.Spec.NodeName) - // We need to call DonePod here because we don't call AddUnschedulableIfNotPresent in this case. - } else { - // As is from SharedInformer, we need to do a DeepCopy() here. - // ignore this err since apiserver doesn't properly validate affinity terms - // and we can't fix the validation for backwards compatibility. - podInfo.PodInfo, _ = framework.NewPodInfo(cachedPod.DeepCopy()) - if err := sched.SchedulingQueue.AddUnschedulableIfNotPresent(logger, podInfo, sched.SchedulingQueue.SchedulingCycle()); err != nil { - logger.Error(err, "Error occurred") - } - calledDone = true - } - } - - // Update the scheduling queue with the nominated pod information. Without - // this, there would be a race condition between the next scheduling cycle - // and the time the scheduler receives a Pod Update for the nominated pod. - // Here we check for nil only for tests. - if sched.SchedulingQueue != nil { - sched.SchedulingQueue.AddNominatedPod(logger, podInfo.PodInfo, nominatingInfo) - } - - if err == nil { - // Only tests can reach here. - return - } - - msg := truncateMessage(errMsg) - fwk.EventRecorder().Eventf(pod, nil, v1.EventTypeWarning, "FailedScheduling", "Scheduling", msg) - if err := updatePod(ctx, sched.client, pod, &v1.PodCondition{ - Type: v1.PodScheduled, - ObservedGeneration: podutil.GetPodObservedGenerationIfEnabledOnCondition(&pod.Status, pod.Generation, v1.PodScheduled), - Status: v1.ConditionFalse, - Reason: reason, - Message: errMsg, - }, nominatingInfo); err != nil { - logger.Error(err, "Error updating pod", "pod", klog.KObj(pod)) - } -} - -// truncateMessage truncates a message if it hits the NoteLengthLimit. -func truncateMessage(message string) string { - max := validation.NoteLengthLimit - if len(message) <= max { - return message - } - suffix := " ..." - return message[:max-len(suffix)] + suffix -} - -func updatePod(ctx context.Context, client clientset.Interface, pod *v1.Pod, condition *v1.PodCondition, nominatingInfo *framework.NominatingInfo) error { - logger := klog.FromContext(ctx) - logger.V(3).Info("Updating pod condition", "pod", klog.KObj(pod), "conditionType", condition.Type, "conditionStatus", condition.Status, "conditionReason", condition.Reason) - podStatusCopy := pod.Status.DeepCopy() - // NominatedNodeName is updated only if we are trying to set it, and the value is - // different from the existing one. - nnnNeedsUpdate := nominatingInfo.Mode() == framework.ModeOverride && pod.Status.NominatedNodeName != nominatingInfo.NominatedNodeName - if !podutil.UpdatePodCondition(podStatusCopy, condition) && !nnnNeedsUpdate { - return nil - } - if nnnNeedsUpdate { - podStatusCopy.NominatedNodeName = nominatingInfo.NominatedNodeName - } - return util.PatchPodStatus(ctx, client, pod, podStatusCopy) -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go b/vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go deleted file mode 100644 index 0fd972fbc..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/scheduler.go +++ /dev/null @@ -1,617 +0,0 @@ -/* -Copyright 2014 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package scheduler - -import ( - "context" - "errors" - "fmt" - "time" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/meta" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" - "k8s.io/client-go/dynamic/dynamicinformer" - "k8s.io/client-go/informers" - coreinformers "k8s.io/client-go/informers/core/v1" - clientset "k8s.io/client-go/kubernetes" - restclient "k8s.io/client-go/rest" - "k8s.io/client-go/tools/cache" - resourceslicetracker "k8s.io/dynamic-resource-allocation/resourceslice/tracker" - "k8s.io/klog/v2" - configv1 "k8s.io/kube-scheduler/config/v1" - "k8s.io/kubernetes/pkg/features" - schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config" - "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme" - internalcache "k8s.io/kubernetes/pkg/scheduler/backend/cache" - cachedebugger "k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger" - internalqueue "k8s.io/kubernetes/pkg/scheduler/backend/queue" - "k8s.io/kubernetes/pkg/scheduler/framework" - "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" - frameworkplugins "k8s.io/kubernetes/pkg/scheduler/framework/plugins" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources" - "k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources" - frameworkruntime "k8s.io/kubernetes/pkg/scheduler/framework/runtime" - "k8s.io/kubernetes/pkg/scheduler/metrics" - "k8s.io/kubernetes/pkg/scheduler/profile" - "k8s.io/kubernetes/pkg/scheduler/util/assumecache" - "k8s.io/utils/clock" -) - -const ( - // Duration the scheduler will wait before expiring an assumed pod. - // See issue #106361 for more details about this parameter and its value. - durationToExpireAssumedPod time.Duration = 0 -) - -// ErrNoNodesAvailable is used to describe the error that no nodes available to schedule pods. -var ErrNoNodesAvailable = fmt.Errorf("no nodes available to schedule pods") - -// Scheduler watches for new unscheduled pods. It attempts to find -// nodes that they fit on and writes bindings back to the api server. -type Scheduler struct { - // It is expected that changes made via Cache will be observed - // by NodeLister and Algorithm. - Cache internalcache.Cache - - Extenders []framework.Extender - - // NextPod should be a function that blocks until the next pod - // is available. We don't use a channel for this, because scheduling - // a pod may take some amount of time and we don't want pods to get - // stale while they sit in a channel. - NextPod func(logger klog.Logger) (*framework.QueuedPodInfo, error) - - // FailureHandler is called upon a scheduling failure. - FailureHandler FailureHandlerFn - - // SchedulePod tries to schedule the given pod to one of the nodes in the node list. - // Return a struct of ScheduleResult with the name of suggested host on success, - // otherwise will return a FitError with reasons. - SchedulePod func(ctx context.Context, fwk framework.Framework, state *framework.CycleState, pod *v1.Pod) (ScheduleResult, error) - - // Close this to shut down the scheduler. - StopEverything <-chan struct{} - - // SchedulingQueue holds pods to be scheduled - SchedulingQueue internalqueue.SchedulingQueue - - // Profiles are the scheduling profiles. - Profiles profile.Map - - client clientset.Interface - - nodeInfoSnapshot *internalcache.Snapshot - - percentageOfNodesToScore int32 - - nextStartNodeIndex int - - // logger *must* be initialized when creating a Scheduler, - // otherwise logging functions will access a nil sink and - // panic. - logger klog.Logger - - // registeredHandlers contains the registrations of all handlers. It's used to check if all handlers have finished syncing before the scheduling cycles start. - registeredHandlers []cache.ResourceEventHandlerRegistration -} - -func (sched *Scheduler) applyDefaultHandlers() { - sched.SchedulePod = sched.schedulePod - sched.FailureHandler = sched.handleSchedulingFailure -} - -type schedulerOptions struct { - clock clock.WithTicker - componentConfigVersion string - kubeConfig *restclient.Config - // Overridden by profile level percentageOfNodesToScore if set in v1. - percentageOfNodesToScore int32 - podInitialBackoffSeconds int64 - podMaxBackoffSeconds int64 - podMaxInUnschedulablePodsDuration time.Duration - // Contains out-of-tree plugins to be merged with the in-tree registry. - frameworkOutOfTreeRegistry frameworkruntime.Registry - profiles []schedulerapi.KubeSchedulerProfile - extenders []schedulerapi.Extender - frameworkCapturer FrameworkCapturer - parallelism int32 - applyDefaultProfile bool -} - -// Option configures a Scheduler -type Option func(*schedulerOptions) - -// ScheduleResult represents the result of scheduling a pod. -type ScheduleResult struct { - // Name of the selected node. - SuggestedHost string - // The number of nodes the scheduler evaluated the pod against in the filtering - // phase and beyond. - EvaluatedNodes int - // The number of nodes out of the evaluated ones that fit the pod. - FeasibleNodes int - // The nominating info for scheduling cycle. - nominatingInfo *framework.NominatingInfo -} - -// WithComponentConfigVersion sets the component config version to the -// KubeSchedulerConfiguration version used. The string should be the full -// scheme group/version of the external type we converted from (for example -// "kubescheduler.config.k8s.io/v1") -func WithComponentConfigVersion(apiVersion string) Option { - return func(o *schedulerOptions) { - o.componentConfigVersion = apiVersion - } -} - -// WithKubeConfig sets the kube config for Scheduler. -func WithKubeConfig(cfg *restclient.Config) Option { - return func(o *schedulerOptions) { - o.kubeConfig = cfg - } -} - -// WithProfiles sets profiles for Scheduler. By default, there is one profile -// with the name "default-scheduler". -func WithProfiles(p ...schedulerapi.KubeSchedulerProfile) Option { - return func(o *schedulerOptions) { - o.profiles = p - o.applyDefaultProfile = false - } -} - -// WithParallelism sets the parallelism for all scheduler algorithms. Default is 16. -func WithParallelism(threads int32) Option { - return func(o *schedulerOptions) { - o.parallelism = threads - } -} - -// WithPercentageOfNodesToScore sets percentageOfNodesToScore for Scheduler. -// The default value of 0 will use an adaptive percentage: 50 - (num of nodes)/125. -func WithPercentageOfNodesToScore(percentageOfNodesToScore *int32) Option { - return func(o *schedulerOptions) { - if percentageOfNodesToScore != nil { - o.percentageOfNodesToScore = *percentageOfNodesToScore - } - } -} - -// WithFrameworkOutOfTreeRegistry sets the registry for out-of-tree plugins. Those plugins -// will be appended to the default registry. -func WithFrameworkOutOfTreeRegistry(registry frameworkruntime.Registry) Option { - return func(o *schedulerOptions) { - o.frameworkOutOfTreeRegistry = registry - } -} - -// WithPodInitialBackoffSeconds sets podInitialBackoffSeconds for Scheduler, the default value is 1 -func WithPodInitialBackoffSeconds(podInitialBackoffSeconds int64) Option { - return func(o *schedulerOptions) { - o.podInitialBackoffSeconds = podInitialBackoffSeconds - } -} - -// WithPodMaxBackoffSeconds sets podMaxBackoffSeconds for Scheduler, the default value is 10 -func WithPodMaxBackoffSeconds(podMaxBackoffSeconds int64) Option { - return func(o *schedulerOptions) { - o.podMaxBackoffSeconds = podMaxBackoffSeconds - } -} - -// WithPodMaxInUnschedulablePodsDuration sets podMaxInUnschedulablePodsDuration for PriorityQueue. -func WithPodMaxInUnschedulablePodsDuration(duration time.Duration) Option { - return func(o *schedulerOptions) { - o.podMaxInUnschedulablePodsDuration = duration - } -} - -// WithExtenders sets extenders for the Scheduler -func WithExtenders(e ...schedulerapi.Extender) Option { - return func(o *schedulerOptions) { - o.extenders = e - } -} - -// WithClock sets clock for PriorityQueue, the default clock is clock.RealClock. -func WithClock(clock clock.WithTicker) Option { - return func(o *schedulerOptions) { - o.clock = clock - } -} - -// FrameworkCapturer is used for registering a notify function in building framework. -type FrameworkCapturer func(schedulerapi.KubeSchedulerProfile) - -// WithBuildFrameworkCapturer sets a notify function for getting buildFramework details. -func WithBuildFrameworkCapturer(fc FrameworkCapturer) Option { - return func(o *schedulerOptions) { - o.frameworkCapturer = fc - } -} - -var defaultSchedulerOptions = schedulerOptions{ - clock: clock.RealClock{}, - percentageOfNodesToScore: schedulerapi.DefaultPercentageOfNodesToScore, - podInitialBackoffSeconds: int64(internalqueue.DefaultPodInitialBackoffDuration.Seconds()), - podMaxBackoffSeconds: int64(internalqueue.DefaultPodMaxBackoffDuration.Seconds()), - podMaxInUnschedulablePodsDuration: internalqueue.DefaultPodMaxInUnschedulablePodsDuration, - parallelism: int32(parallelize.DefaultParallelism), - // Ideally we would statically set the default profile here, but we can't because - // creating the default profile may require testing feature gates, which may get - // set dynamically in tests. Therefore, we delay creating it until New is actually - // invoked. - applyDefaultProfile: true, -} - -// New returns a Scheduler -func New(ctx context.Context, - client clientset.Interface, - informerFactory informers.SharedInformerFactory, - dynInformerFactory dynamicinformer.DynamicSharedInformerFactory, - recorderFactory profile.RecorderFactory, - opts ...Option) (*Scheduler, error) { - - logger := klog.FromContext(ctx) - stopEverything := ctx.Done() - - options := defaultSchedulerOptions - for _, opt := range opts { - opt(&options) - } - - if options.applyDefaultProfile { - var versionedCfg configv1.KubeSchedulerConfiguration - scheme.Scheme.Default(&versionedCfg) - cfg := schedulerapi.KubeSchedulerConfiguration{} - if err := scheme.Scheme.Convert(&versionedCfg, &cfg, nil); err != nil { - return nil, err - } - options.profiles = cfg.Profiles - } - - registry := frameworkplugins.NewInTreeRegistry() - if err := registry.Merge(options.frameworkOutOfTreeRegistry); err != nil { - return nil, err - } - - metrics.Register() - - extenders, err := buildExtenders(logger, options.extenders, options.profiles) - if err != nil { - return nil, fmt.Errorf("couldn't build extenders: %w", err) - } - - podLister := informerFactory.Core().V1().Pods().Lister() - nodeLister := informerFactory.Core().V1().Nodes().Lister() - - snapshot := internalcache.NewEmptySnapshot() - metricsRecorder := metrics.NewMetricsAsyncRecorder(1000, time.Second, stopEverything) - // waitingPods holds all the pods that are in the scheduler and waiting in the permit stage - waitingPods := frameworkruntime.NewWaitingPodsMap() - - var resourceClaimCache *assumecache.AssumeCache - var resourceSliceTracker *resourceslicetracker.Tracker - var draManager framework.SharedDRAManager - if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) { - resourceClaimInformer := informerFactory.Resource().V1beta1().ResourceClaims().Informer() - resourceClaimCache = assumecache.NewAssumeCache(logger, resourceClaimInformer, "ResourceClaim", "", nil) - resourceSliceTrackerOpts := resourceslicetracker.Options{ - EnableDeviceTaints: utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceTaints), - SliceInformer: informerFactory.Resource().V1beta1().ResourceSlices(), - KubeClient: client, - } - // If device taints are disabled, the additional informers are not needed and - // the tracker turns into a simple wrapper around the slice informer. - if resourceSliceTrackerOpts.EnableDeviceTaints { - resourceSliceTrackerOpts.TaintInformer = informerFactory.Resource().V1alpha3().DeviceTaintRules() - resourceSliceTrackerOpts.ClassInformer = informerFactory.Resource().V1beta1().DeviceClasses() - } - resourceSliceTracker, err = resourceslicetracker.StartTracker(ctx, resourceSliceTrackerOpts) - if err != nil { - return nil, fmt.Errorf("couldn't start resource slice tracker: %w", err) - } - draManager = dynamicresources.NewDRAManager(ctx, resourceClaimCache, resourceSliceTracker, informerFactory) - } - - profiles, err := profile.NewMap(ctx, options.profiles, registry, recorderFactory, - frameworkruntime.WithComponentConfigVersion(options.componentConfigVersion), - frameworkruntime.WithClientSet(client), - frameworkruntime.WithKubeConfig(options.kubeConfig), - frameworkruntime.WithInformerFactory(informerFactory), - frameworkruntime.WithSharedDRAManager(draManager), - frameworkruntime.WithSnapshotSharedLister(snapshot), - frameworkruntime.WithCaptureProfile(frameworkruntime.CaptureProfile(options.frameworkCapturer)), - frameworkruntime.WithParallelism(int(options.parallelism)), - frameworkruntime.WithExtenders(extenders), - frameworkruntime.WithMetricsRecorder(metricsRecorder), - frameworkruntime.WithWaitingPods(waitingPods), - ) - if err != nil { - return nil, fmt.Errorf("initializing profiles: %v", err) - } - - if len(profiles) == 0 { - return nil, errors.New("at least one profile is required") - } - - preEnqueuePluginMap := make(map[string][]framework.PreEnqueuePlugin) - queueingHintsPerProfile := make(internalqueue.QueueingHintMapPerProfile) - var returnErr error - for profileName, profile := range profiles { - preEnqueuePluginMap[profileName] = profile.PreEnqueuePlugins() - queueingHintsPerProfile[profileName], err = buildQueueingHintMap(ctx, profile.EnqueueExtensions()) - if err != nil { - returnErr = errors.Join(returnErr, err) - } - } - - if returnErr != nil { - return nil, returnErr - } - - podQueue := internalqueue.NewSchedulingQueue( - profiles[options.profiles[0].SchedulerName].QueueSortFunc(), - informerFactory, - internalqueue.WithClock(options.clock), - internalqueue.WithPodInitialBackoffDuration(time.Duration(options.podInitialBackoffSeconds)*time.Second), - internalqueue.WithPodMaxBackoffDuration(time.Duration(options.podMaxBackoffSeconds)*time.Second), - internalqueue.WithPodLister(podLister), - internalqueue.WithPodMaxInUnschedulablePodsDuration(options.podMaxInUnschedulablePodsDuration), - internalqueue.WithPreEnqueuePluginMap(preEnqueuePluginMap), - internalqueue.WithQueueingHintMapPerProfile(queueingHintsPerProfile), - internalqueue.WithPluginMetricsSamplePercent(pluginMetricsSamplePercent), - internalqueue.WithMetricsRecorder(*metricsRecorder), - ) - - for _, fwk := range profiles { - fwk.SetPodNominator(podQueue) - fwk.SetPodActivator(podQueue) - } - - schedulerCache := internalcache.New(ctx, durationToExpireAssumedPod) - - // Setup cache debugger. - debugger := cachedebugger.New(nodeLister, podLister, schedulerCache, podQueue) - debugger.ListenForSignal(ctx) - - sched := &Scheduler{ - Cache: schedulerCache, - client: client, - nodeInfoSnapshot: snapshot, - percentageOfNodesToScore: options.percentageOfNodesToScore, - Extenders: extenders, - StopEverything: stopEverything, - SchedulingQueue: podQueue, - Profiles: profiles, - logger: logger, - } - sched.NextPod = podQueue.Pop - sched.applyDefaultHandlers() - - if err = addAllEventHandlers(sched, informerFactory, dynInformerFactory, resourceClaimCache, resourceSliceTracker, unionedGVKs(queueingHintsPerProfile)); err != nil { - return nil, fmt.Errorf("adding event handlers: %w", err) - } - - return sched, nil -} - -// defaultQueueingHintFn is the default queueing hint function. -// It always returns Queue as the queueing hint. -var defaultQueueingHintFn = func(_ klog.Logger, _ *v1.Pod, _, _ interface{}) (framework.QueueingHint, error) { - return framework.Queue, nil -} - -func buildQueueingHintMap(ctx context.Context, es []framework.EnqueueExtensions) (internalqueue.QueueingHintMap, error) { - queueingHintMap := make(internalqueue.QueueingHintMap) - var returnErr error - for _, e := range es { - events, err := e.EventsToRegister(ctx) - if err != nil { - returnErr = errors.Join(returnErr, err) - } - - // This will happen when plugin registers with empty events, it's usually the case a pod - // will become reschedulable only for self-update, e.g. schedulingGates plugin, the pod - // will enter into the activeQ via priorityQueue.Update(). - if len(events) == 0 { - continue - } - - // Note: Rarely, a plugin implements EnqueueExtensions but returns nil. - // We treat it as: the plugin is not interested in any event, and hence pod failed by that plugin - // cannot be moved by any regular cluster event. - // So, we can just ignore such EventsToRegister here. - - registerNodeAdded := false - registerNodeTaintUpdated := false - for _, event := range events { - fn := event.QueueingHintFn - if fn == nil || !utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { - fn = defaultQueueingHintFn - } - - if event.Event.Resource == framework.Node { - if event.Event.ActionType&framework.Add != 0 { - registerNodeAdded = true - } - if event.Event.ActionType&framework.UpdateNodeTaint != 0 { - registerNodeTaintUpdated = true - } - } - - queueingHintMap[event.Event] = append(queueingHintMap[event.Event], &internalqueue.QueueingHintFunction{ - PluginName: e.Name(), - QueueingHintFn: fn, - }) - } - if registerNodeAdded && !registerNodeTaintUpdated { - // Temporally fix for the issue https://github.com/kubernetes/kubernetes/issues/109437 - // NodeAdded QueueingHint isn't always called because of preCheck. - // It's definitely not something expected for plugin developers, - // and registering UpdateNodeTaint event is the only mitigation for now. - // - // So, here registers UpdateNodeTaint event for plugins that has NodeAdded event, but don't have UpdateNodeTaint event. - // It has a bad impact for the requeuing efficiency though, a lot better than some Pods being stuch in the - // unschedulable pod pool. - // This behavior will be removed when we remove the preCheck feature. - // See: https://github.com/kubernetes/kubernetes/issues/110175 - queueingHintMap[framework.ClusterEvent{Resource: framework.Node, ActionType: framework.UpdateNodeTaint}] = - append(queueingHintMap[framework.ClusterEvent{Resource: framework.Node, ActionType: framework.UpdateNodeTaint}], - &internalqueue.QueueingHintFunction{ - PluginName: e.Name(), - QueueingHintFn: defaultQueueingHintFn, - }, - ) - } - } - if returnErr != nil { - return nil, returnErr - } - return queueingHintMap, nil -} - -// Run begins watching and scheduling. It starts scheduling and blocked until the context is done. -func (sched *Scheduler) Run(ctx context.Context) { - logger := klog.FromContext(ctx) - sched.SchedulingQueue.Run(logger) - - // We need to start scheduleOne loop in a dedicated goroutine, - // because scheduleOne function hangs on getting the next item - // from the SchedulingQueue. - // If there are no new pods to schedule, it will be hanging there - // and if done in this goroutine it will be blocking closing - // SchedulingQueue, in effect causing a deadlock on shutdown. - go wait.UntilWithContext(ctx, sched.ScheduleOne, 0) - - <-ctx.Done() - sched.SchedulingQueue.Close() - - // If the plugins satisfy the io.Closer interface, they are closed. - err := sched.Profiles.Close() - if err != nil { - logger.Error(err, "Failed to close plugins") - } -} - -// NewInformerFactory creates a SharedInformerFactory and initializes a scheduler specific -// in-place podInformer. -func NewInformerFactory(cs clientset.Interface, resyncPeriod time.Duration) informers.SharedInformerFactory { - informerFactory := informers.NewSharedInformerFactory(cs, resyncPeriod) - informerFactory.InformerFor(&v1.Pod{}, newPodInformer) - return informerFactory -} - -func buildExtenders(logger klog.Logger, extenders []schedulerapi.Extender, profiles []schedulerapi.KubeSchedulerProfile) ([]framework.Extender, error) { - var fExtenders []framework.Extender - if len(extenders) == 0 { - return nil, nil - } - - var ignoredExtendedResources []string - var ignorableExtenders []framework.Extender - for i := range extenders { - logger.V(2).Info("Creating extender", "extender", extenders[i]) - extender, err := NewHTTPExtender(&extenders[i]) - if err != nil { - return nil, err - } - if !extender.IsIgnorable() { - fExtenders = append(fExtenders, extender) - } else { - ignorableExtenders = append(ignorableExtenders, extender) - } - for _, r := range extenders[i].ManagedResources { - if r.IgnoredByScheduler { - ignoredExtendedResources = append(ignoredExtendedResources, r.Name) - } - } - } - // place ignorable extenders to the tail of extenders - fExtenders = append(fExtenders, ignorableExtenders...) - - // If there are any extended resources found from the Extenders, append them to the pluginConfig for each profile. - // This should only have an effect on ComponentConfig, where it is possible to configure Extenders and - // plugin args (and in which case the extender ignored resources take precedence). - if len(ignoredExtendedResources) == 0 { - return fExtenders, nil - } - - for i := range profiles { - prof := &profiles[i] - var found = false - for k := range prof.PluginConfig { - if prof.PluginConfig[k].Name == noderesources.Name { - // Update the existing args - pc := &prof.PluginConfig[k] - args, ok := pc.Args.(*schedulerapi.NodeResourcesFitArgs) - if !ok { - return nil, fmt.Errorf("want args to be of type NodeResourcesFitArgs, got %T", pc.Args) - } - args.IgnoredResources = ignoredExtendedResources - found = true - break - } - } - if !found { - return nil, fmt.Errorf("can't find NodeResourcesFitArgs in plugin config") - } - } - return fExtenders, nil -} - -type FailureHandlerFn func(ctx context.Context, fwk framework.Framework, podInfo *framework.QueuedPodInfo, status *framework.Status, nominatingInfo *framework.NominatingInfo, start time.Time) - -func unionedGVKs(queueingHintsPerProfile internalqueue.QueueingHintMapPerProfile) map[framework.EventResource]framework.ActionType { - gvkMap := make(map[framework.EventResource]framework.ActionType) - for _, queueingHints := range queueingHintsPerProfile { - for evt := range queueingHints { - if _, ok := gvkMap[evt.Resource]; ok { - gvkMap[evt.Resource] |= evt.ActionType - } else { - gvkMap[evt.Resource] = evt.ActionType - } - } - } - return gvkMap -} - -// newPodInformer creates a shared index informer that returns only non-terminal pods. -// The PodInformer allows indexers to be added, but note that only non-conflict indexers are allowed. -func newPodInformer(cs clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { - selector := fmt.Sprintf("status.phase!=%v,status.phase!=%v", v1.PodSucceeded, v1.PodFailed) - tweakListOptions := func(options *metav1.ListOptions) { - options.FieldSelector = selector - } - informer := coreinformers.NewFilteredPodInformer(cs, metav1.NamespaceAll, resyncPeriod, cache.Indexers{}, tweakListOptions) - - // Dropping `.metadata.managedFields` to improve memory usage. - // The Extract workflow (i.e. `ExtractPod`) should be unused. - trim := func(obj interface{}) (interface{}, error) { - if accessor, err := meta.Accessor(obj); err == nil { - if accessor.GetManagedFields() != nil { - accessor.SetManagedFields(nil) - } - } - return obj, nil - } - informer.SetTransform(trim) - return informer -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go b/vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go deleted file mode 100644 index c7392129c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/util/assumecache/assume_cache.go +++ /dev/null @@ -1,531 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package assumecache - -import ( - "errors" - "fmt" - "strconv" - "sync" - - "k8s.io/klog/v2" - - "k8s.io/apimachinery/pkg/api/meta" - utilruntime "k8s.io/apimachinery/pkg/util/runtime" - "k8s.io/client-go/tools/cache" - "k8s.io/kubernetes/pkg/scheduler/util/queue" -) - -// Informer is the subset of [cache.SharedInformer] that NewAssumeCache depends upon. -type Informer interface { - AddEventHandler(handler cache.ResourceEventHandler) (cache.ResourceEventHandlerRegistration, error) -} - -// AddTestObject adds an object to the assume cache. -// Only use this for unit testing! -func AddTestObject(cache *AssumeCache, obj interface{}) { - cache.add(obj) -} - -// UpdateTestObject updates an object in the assume cache. -// Only use this for unit testing! -func UpdateTestObject(cache *AssumeCache, obj interface{}) { - cache.update(nil, obj) -} - -// DeleteTestObject deletes object in the assume cache. -// Only use this for unit testing! -func DeleteTestObject(cache *AssumeCache, obj interface{}) { - cache.delete(obj) -} - -// Sentinel errors that can be checked for with errors.Is. -var ( - ErrWrongType = errors.New("object has wrong type") - ErrNotFound = errors.New("object not found") - ErrObjectName = errors.New("cannot determine object name") -) - -type WrongTypeError struct { - TypeName string - Object interface{} -} - -func (e WrongTypeError) Error() string { - return fmt.Sprintf("could not convert object to type %v: %+v", e.TypeName, e.Object) -} - -func (e WrongTypeError) Is(err error) bool { - return err == ErrWrongType -} - -type NotFoundError struct { - TypeName string - ObjectKey string -} - -func (e NotFoundError) Error() string { - return fmt.Sprintf("could not find %v %q", e.TypeName, e.ObjectKey) -} - -func (e NotFoundError) Is(err error) bool { - return err == ErrNotFound -} - -type ObjectNameError struct { - DetailedErr error -} - -func (e ObjectNameError) Error() string { - return fmt.Sprintf("failed to get object name: %v", e.DetailedErr) -} - -func (e ObjectNameError) Is(err error) bool { - return err == ErrObjectName -} - -// AssumeCache is a cache on top of the informer that allows for updating -// objects outside of informer events and also restoring the informer -// cache's version of the object. Objects are assumed to be -// Kubernetes API objects that are supported by [meta.Accessor]. -// -// Objects can referenced via their key, with [cache.MetaNamespaceKeyFunc] -// as key function. -// -// AssumeCache stores two pointers to represent a single object: -// - The pointer to the informer object. -// - The pointer to the latest object, which could be the same as -// the informer object, or an in-memory object. -// -// An informer update always overrides the latest object pointer. -// -// Assume() only updates the latest object pointer. -// Restore() sets the latest object pointer back to the informer object. -// Get/List() always returns the latest object pointer. -type AssumeCache struct { - // The logger that was chosen when setting up the cache. - // Will be used for all operations. - logger klog.Logger - - // Synchronizes updates to all fields below. - rwMutex sync.RWMutex - - // All registered event handlers. - eventHandlers []cache.ResourceEventHandler - handlerRegistration cache.ResourceEventHandlerRegistration - - // The eventQueue contains functions which deliver an event to one - // event handler. - // - // These functions must be invoked while *not locking* rwMutex because - // the event handlers are allowed to access the assume cache. Holding - // rwMutex then would cause a deadlock. - // - // New functions get added as part of processing a cache update while - // the rwMutex is locked. Each function which adds something to the queue - // also drains the queue before returning, therefore it is guaranteed - // that all event handlers get notified immediately (useful for unit - // testing). - // - // A channel cannot be used here because it cannot have an unbounded - // capacity. This could lead to a deadlock (writer holds rwMutex, - // gets blocked because capacity is exhausted, reader is in a handler - // which tries to lock the rwMutex). Writing into such a channel - // while not holding the rwMutex doesn't work because in-order delivery - // of events would no longer be guaranteed. - eventQueue queue.FIFO[func()] - - // describes the object stored - description string - - // Stores objInfo pointers - store cache.Indexer - - // Index function for object - indexFunc cache.IndexFunc - indexName string -} - -type objInfo struct { - // name of the object - name string - - // Latest version of object could be cached-only or from informer - latestObj interface{} - - // Latest object from informer - apiObj interface{} -} - -func objInfoKeyFunc(obj interface{}) (string, error) { - objInfo, ok := obj.(*objInfo) - if !ok { - return "", &WrongTypeError{TypeName: "objInfo", Object: obj} - } - return objInfo.name, nil -} - -func (c *AssumeCache) objInfoIndexFunc(obj interface{}) ([]string, error) { - objInfo, ok := obj.(*objInfo) - if !ok { - return []string{""}, &WrongTypeError{TypeName: "objInfo", Object: obj} - } - return c.indexFunc(objInfo.latestObj) -} - -// NewAssumeCache creates an assume cache for general objects. -func NewAssumeCache(logger klog.Logger, informer Informer, description, indexName string, indexFunc cache.IndexFunc) *AssumeCache { - c := &AssumeCache{ - logger: logger, - description: description, - indexFunc: indexFunc, - indexName: indexName, - } - indexers := cache.Indexers{} - if indexName != "" && indexFunc != nil { - indexers[indexName] = c.objInfoIndexFunc - } - c.store = cache.NewIndexer(objInfoKeyFunc, indexers) - - // Unit tests don't use informers - if informer != nil { - // Cannot fail in practice?! No-one bothers checking the error. - c.handlerRegistration, _ = informer.AddEventHandler( - cache.ResourceEventHandlerFuncs{ - AddFunc: c.add, - UpdateFunc: c.update, - DeleteFunc: c.delete, - }, - ) - } - return c -} - -func (c *AssumeCache) add(obj interface{}) { - if obj == nil { - return - } - - name, err := cache.MetaNamespaceKeyFunc(obj) - if err != nil { - c.logger.Error(&ObjectNameError{err}, "Add failed") - return - } - - defer c.emitEvents() - c.rwMutex.Lock() - defer c.rwMutex.Unlock() - - var oldObj interface{} - if objInfo, _ := c.getObjInfo(name); objInfo != nil { - newVersion, err := c.getObjVersion(name, obj) - if err != nil { - c.logger.Error(err, "Add failed: couldn't get object version") - return - } - - storedVersion, err := c.getObjVersion(name, objInfo.latestObj) - if err != nil { - c.logger.Error(err, "Add failed: couldn't get stored object version") - return - } - - // Only update object if version is newer. - // This is so we don't override assumed objects due to informer resync. - if newVersion <= storedVersion { - c.logger.V(10).Info("Skip adding object to assume cache because version is not newer than storedVersion", "description", c.description, "cacheKey", name, "newVersion", newVersion, "storedVersion", storedVersion) - return - } - oldObj = objInfo.latestObj - } - - objInfo := &objInfo{name: name, latestObj: obj, apiObj: obj} - if err = c.store.Update(objInfo); err != nil { - c.logger.Info("Error occurred while updating stored object", "err", err) - } else { - c.logger.V(10).Info("Adding object to assume cache", "description", c.description, "cacheKey", name, "assumeCache", obj) - c.pushEvent(oldObj, obj) - } -} - -func (c *AssumeCache) update(oldObj interface{}, newObj interface{}) { - c.add(newObj) -} - -func (c *AssumeCache) delete(obj interface{}) { - if obj == nil { - return - } - - name, err := cache.DeletionHandlingMetaNamespaceKeyFunc(obj) - if err != nil { - c.logger.Error(&ObjectNameError{err}, "Failed to delete") - return - } - - defer c.emitEvents() - c.rwMutex.Lock() - defer c.rwMutex.Unlock() - - var oldObj interface{} - if len(c.eventHandlers) > 0 { - if objInfo, _ := c.getObjInfo(name); objInfo != nil { - oldObj = objInfo.latestObj - } - } - - objInfo := &objInfo{name: name} - err = c.store.Delete(objInfo) - if err != nil { - c.logger.Error(err, "Failed to delete", "description", c.description, "cacheKey", name) - } - - c.pushEvent(oldObj, nil) -} - -// pushEvent gets called while the mutex is locked for writing. -// It ensures that all currently registered event handlers get -// notified about a change when the caller starts delivering -// those with emitEvents. -// -// For a delete event, newObj is nil. For an add, oldObj is nil. -// An update has both as non-nil. -func (c *AssumeCache) pushEvent(oldObj, newObj interface{}) { - for _, handler := range c.eventHandlers { - handler := handler - if oldObj == nil { - c.eventQueue.Push(func() { - handler.OnAdd(newObj, false) - }) - } else if newObj == nil { - c.eventQueue.Push(func() { - handler.OnDelete(oldObj) - }) - } else { - c.eventQueue.Push(func() { - handler.OnUpdate(oldObj, newObj) - }) - } - } -} - -func (c *AssumeCache) getObjVersion(name string, obj interface{}) (int64, error) { - objAccessor, err := meta.Accessor(obj) - if err != nil { - return -1, err - } - - objResourceVersion, err := strconv.ParseInt(objAccessor.GetResourceVersion(), 10, 64) - if err != nil { - //nolint:errorlint // Intentionally not wrapping the error, the underlying error is an implementation detail. - return -1, fmt.Errorf("error parsing ResourceVersion %q for %v %q: %v", objAccessor.GetResourceVersion(), c.description, name, err) - } - return objResourceVersion, nil -} - -func (c *AssumeCache) getObjInfo(key string) (*objInfo, error) { - obj, ok, err := c.store.GetByKey(key) - if err != nil { - return nil, err - } - if !ok { - return nil, &NotFoundError{TypeName: c.description, ObjectKey: key} - } - - objInfo, ok := obj.(*objInfo) - if !ok { - return nil, &WrongTypeError{"objInfo", obj} - } - return objInfo, nil -} - -// Get the object by its key. -func (c *AssumeCache) Get(key string) (interface{}, error) { - c.rwMutex.RLock() - defer c.rwMutex.RUnlock() - - objInfo, err := c.getObjInfo(key) - if err != nil { - return nil, err - } - return objInfo.latestObj, nil -} - -// GetAPIObj gets the informer cache's version by its key. -func (c *AssumeCache) GetAPIObj(key string) (interface{}, error) { - c.rwMutex.RLock() - defer c.rwMutex.RUnlock() - - objInfo, err := c.getObjInfo(key) - if err != nil { - return nil, err - } - return objInfo.apiObj, nil -} - -// List all the objects in the cache. -func (c *AssumeCache) List(indexObj interface{}) []interface{} { - c.rwMutex.RLock() - defer c.rwMutex.RUnlock() - - return c.listLocked(indexObj) -} - -func (c *AssumeCache) listLocked(indexObj interface{}) []interface{} { - allObjs := []interface{}{} - var objs []interface{} - if c.indexName != "" { - o, err := c.store.Index(c.indexName, &objInfo{latestObj: indexObj}) - if err != nil { - c.logger.Error(err, "List index error") - return nil - } - objs = o - } else { - objs = c.store.List() - } - - for _, obj := range objs { - objInfo, ok := obj.(*objInfo) - if !ok { - c.logger.Error(&WrongTypeError{TypeName: "objInfo", Object: obj}, "List error") - continue - } - allObjs = append(allObjs, objInfo.latestObj) - } - return allObjs -} - -// Assume updates the object in-memory only. -// -// The version of the object must be greater or equal to -// the current object, otherwise an error is returned. -// -// Storing an object with the same version is supported -// by the assume cache, but suffers from a race: if an -// update is received via the informer while such an -// object is assumed, it gets dropped in favor of the -// newer object from the apiserver. -// -// Only assuming objects that were returned by an apiserver -// operation (Update, Patch) is safe. -func (c *AssumeCache) Assume(obj interface{}) error { - name, err := cache.MetaNamespaceKeyFunc(obj) - if err != nil { - return &ObjectNameError{err} - } - - defer c.emitEvents() - c.rwMutex.Lock() - defer c.rwMutex.Unlock() - - objInfo, err := c.getObjInfo(name) - if err != nil { - return err - } - - newVersion, err := c.getObjVersion(name, obj) - if err != nil { - return err - } - - storedVersion, err := c.getObjVersion(name, objInfo.latestObj) - if err != nil { - return err - } - - if newVersion < storedVersion { - return fmt.Errorf("%v %q is out of sync (stored: %d, assume: %d)", c.description, name, storedVersion, newVersion) - } - - c.pushEvent(objInfo.latestObj, obj) - - // Only update the cached object - objInfo.latestObj = obj - c.logger.V(4).Info("Assumed object", "description", c.description, "cacheKey", name, "version", newVersion) - return nil -} - -// Restore the informer cache's version of the object. -func (c *AssumeCache) Restore(objName string) { - defer c.emitEvents() - c.rwMutex.Lock() - defer c.rwMutex.Unlock() - - objInfo, err := c.getObjInfo(objName) - if err != nil { - // This could be expected if object got deleted - c.logger.V(5).Info("Restore object", "description", c.description, "cacheKey", objName, "err", err) - } else { - if objInfo.latestObj != objInfo.apiObj { - c.pushEvent(objInfo.latestObj, objInfo.apiObj) - objInfo.latestObj = objInfo.apiObj - } - c.logger.V(4).Info("Restored object", "description", c.description, "cacheKey", objName) - } -} - -// AddEventHandler adds an event handler to the cache. Events to a -// single handler are delivered sequentially, but there is no -// coordination between different handlers. A handler may use the -// cache. -// -// The return value can be used to wait for cache synchronization. -func (c *AssumeCache) AddEventHandler(handler cache.ResourceEventHandler) cache.ResourceEventHandlerRegistration { - defer c.emitEvents() - c.rwMutex.Lock() - defer c.rwMutex.Unlock() - - c.eventHandlers = append(c.eventHandlers, handler) - allObjs := c.listLocked(nil) - for _, obj := range allObjs { - c.eventQueue.Push(func() { - handler.OnAdd(obj, true) - }) - } - - if c.handlerRegistration == nil { - // No informer, so immediately synced. - return syncedHandlerRegistration{} - } - - return c.handlerRegistration -} - -// emitEvents delivers all pending events that are in the queue, in the order -// in which they were stored there (FIFO). -func (c *AssumeCache) emitEvents() { - for { - c.rwMutex.Lock() - deliver, ok := c.eventQueue.Pop() - c.rwMutex.Unlock() - - if !ok { - return - } - func() { - defer utilruntime.HandleCrash() - deliver() - }() - } -} - -// syncedHandlerRegistration is an implementation of ResourceEventHandlerRegistration -// which always returns true. -type syncedHandlerRegistration struct{} - -func (syncedHandlerRegistration) HasSynced() bool { return true } diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/util/pod_resources.go b/vendor/k8s.io/kubernetes/pkg/scheduler/util/pod_resources.go deleted file mode 100644 index e84568560..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/util/pod_resources.go +++ /dev/null @@ -1,32 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -// For each of these resources, a container that doesn't request the resource explicitly -// will be treated as having requested the amount indicated below, for the purpose -// of computing priority only. This ensures that when scheduling zero-request pods, such -// pods will not all be scheduled to the node with the smallest in-use request, -// and that when scheduling regular pods, such pods will not see zero-request pods as -// consuming no resources whatsoever. We chose these values to be similar to the -// resources that we give to cluster addon pods (#10653). But they are pretty arbitrary. -// As described in #11713, we use request instead of limit to deal with resource requirements. -const ( - // DefaultMilliCPURequest defines default milli cpu request number. - DefaultMilliCPURequest int64 = 100 // 0.1 core - // DefaultMemoryRequest defines default memory request size. - DefaultMemoryRequest int64 = 200 * 1024 * 1024 // 200 MB -) diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/util/queue/fifo.go b/vendor/k8s.io/kubernetes/pkg/scheduler/util/queue/fifo.go deleted file mode 100644 index ee66733fe..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/util/queue/fifo.go +++ /dev/null @@ -1,110 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package queue - -const ( - // normalSize limits the size of the buffer that is kept - // for reuse. - normalSize = 4 -) - -// FIFO implements a first-in-first-out queue with unbounded size. -// The null FIFO is a valid empty queue. -// -// Access must be protected by the caller when used concurrently by -// different goroutines, the queue itself implements no locking. -type FIFO[T any] struct { - // elements contains a buffer for elements which have been - // pushed and not popped yet. Two scenarios are possible: - // - one chunk in the middle (start <= end) - // - one chunk at the end, followed by one chunk at the - // beginning (end <= start) - // - // start == end can be either an empty queue or a completely - // full one (with two chunks). - elements []T - - // len counts the number of elements which have been pushed and - // not popped yet. - len int - - // start is the index of the first valid element. - start int - - // end is the index after the last valid element. - end int -} - -func (q *FIFO[T]) Len() int { - return q.len -} - -func (q *FIFO[T]) Push(element T) { - size := len(q.elements) - if q.len == size { - // Need larger buffer. - newSize := size * 2 - if newSize == 0 { - newSize = normalSize - } - elements := make([]T, newSize) - if q.start == 0 { - copy(elements, q.elements) - } else { - copy(elements, q.elements[q.start:]) - copy(elements[len(q.elements)-q.start:], q.elements[0:q.end]) - } - q.start = 0 - q.end = q.len - q.elements = elements - size = newSize - } - if q.end == size { - // Wrap around. - q.elements[0] = element - q.end = 1 - q.len++ - return - } - q.elements[q.end] = element - q.end++ - q.len++ -} - -func (q *FIFO[T]) Pop() (element T, ok bool) { - if q.len == 0 { - return - } - element = q.elements[q.start] - q.start++ - if q.start == len(q.elements) { - // Wrap around. - q.start = 0 - } - q.len-- - - // Once it is empty, shrink down to avoid hanging onto - // a large buffer forever. - if q.len == 0 && len(q.elements) > normalSize { - q.elements = make([]T, normalSize) - q.start = 0 - q.end = 0 - } - - ok = true - return -} diff --git a/vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go b/vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go deleted file mode 100644 index 751c72757..000000000 --- a/vendor/k8s.io/kubernetes/pkg/scheduler/util/utils.go +++ /dev/null @@ -1,226 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package util - -import ( - "context" - "encoding/json" - "fmt" - "time" - - v1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - utilerrors "k8s.io/apimachinery/pkg/util/errors" - "k8s.io/apimachinery/pkg/util/net" - "k8s.io/apimachinery/pkg/util/strategicpatch" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/cache" - "k8s.io/client-go/util/retry" - corev1helpers "k8s.io/component-helpers/scheduling/corev1" - "k8s.io/klog/v2" - extenderv1 "k8s.io/kube-scheduler/extender/v1" - v1helper "k8s.io/kubernetes/pkg/apis/core/v1/helper" -) - -// GetPodFullName returns a name that uniquely identifies a pod. -func GetPodFullName(pod *v1.Pod) string { - // Use underscore as the delimiter because it is not allowed in pod name - // (DNS subdomain format). - return pod.Name + "_" + pod.Namespace -} - -// GetPodStartTime returns start time of the given pod or current timestamp -// if it hasn't started yet. -func GetPodStartTime(pod *v1.Pod) *metav1.Time { - if pod.Status.StartTime != nil { - return pod.Status.StartTime - } - // Assumed pods and bound pods that haven't started don't have a StartTime yet. - return &metav1.Time{Time: time.Now()} -} - -// GetEarliestPodStartTime returns the earliest start time of all pods that -// have the highest priority among all victims. -func GetEarliestPodStartTime(victims *extenderv1.Victims) *metav1.Time { - if len(victims.Pods) == 0 { - // should not reach here. - klog.Background().Error(nil, "victims.Pods is empty. Should not reach here") - return nil - } - - earliestPodStartTime := GetPodStartTime(victims.Pods[0]) - maxPriority := corev1helpers.PodPriority(victims.Pods[0]) - - for _, pod := range victims.Pods { - if podPriority := corev1helpers.PodPriority(pod); podPriority == maxPriority { - if podStartTime := GetPodStartTime(pod); podStartTime.Before(earliestPodStartTime) { - earliestPodStartTime = podStartTime - } - } else if podPriority > maxPriority { - maxPriority = podPriority - earliestPodStartTime = GetPodStartTime(pod) - } - } - - return earliestPodStartTime -} - -// MoreImportantPod return true when priority of the first pod is higher than -// the second one. If two pods' priorities are equal, compare their StartTime. -// It takes arguments of the type "interface{}" to be used with SortableList, -// but expects those arguments to be *v1.Pod. -func MoreImportantPod(pod1, pod2 *v1.Pod) bool { - p1 := corev1helpers.PodPriority(pod1) - p2 := corev1helpers.PodPriority(pod2) - if p1 != p2 { - return p1 > p2 - } - return GetPodStartTime(pod1).Before(GetPodStartTime(pod2)) -} - -// Retriable defines the retriable errors during a scheduling cycle. -func Retriable(err error) bool { - return apierrors.IsInternalError(err) || apierrors.IsServiceUnavailable(err) || - net.IsConnectionRefused(err) -} - -// PatchPodStatus calculates the delta bytes change from to , -// and then submit a request to API server to patch the pod changes. -func PatchPodStatus(ctx context.Context, cs kubernetes.Interface, old *v1.Pod, newStatus *v1.PodStatus) error { - if newStatus == nil { - return nil - } - - oldData, err := json.Marshal(v1.Pod{Status: old.Status}) - if err != nil { - return err - } - - newData, err := json.Marshal(v1.Pod{Status: *newStatus}) - if err != nil { - return err - } - patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, &v1.Pod{}) - if err != nil { - return fmt.Errorf("failed to create merge patch for pod %q/%q: %v", old.Namespace, old.Name, err) - } - - if "{}" == string(patchBytes) { - return nil - } - - patchFn := func() error { - _, err := cs.CoreV1().Pods(old.Namespace).Patch(ctx, old.Name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status") - return err - } - - return retry.OnError(retry.DefaultBackoff, Retriable, patchFn) -} - -// DeletePod deletes the given from API server -func DeletePod(ctx context.Context, cs kubernetes.Interface, pod *v1.Pod) error { - return cs.CoreV1().Pods(pod.Namespace).Delete(ctx, pod.Name, metav1.DeleteOptions{}) -} - -// ClearNominatedNodeName internally submit a patch request to API server -// to set each pods[*].Status.NominatedNodeName> to "". -func ClearNominatedNodeName(ctx context.Context, cs kubernetes.Interface, pods ...*v1.Pod) utilerrors.Aggregate { - var errs []error - for _, p := range pods { - if len(p.Status.NominatedNodeName) == 0 { - continue - } - podStatusCopy := p.Status.DeepCopy() - podStatusCopy.NominatedNodeName = "" - if err := PatchPodStatus(ctx, cs, p, podStatusCopy); err != nil { - errs = append(errs, err) - } - } - return utilerrors.NewAggregate(errs) -} - -// IsScalarResourceName validates the resource for Extended, Hugepages, Native and AttachableVolume resources -func IsScalarResourceName(name v1.ResourceName) bool { - return v1helper.IsExtendedResourceName(name) || v1helper.IsHugePageResourceName(name) || - v1helper.IsPrefixedNativeResource(name) || v1helper.IsAttachableVolumeResourceName(name) -} - -// As converts two objects to the given type. -// Both objects must be of the same type. If not, an error is returned. -// nil objects are allowed and will be converted to nil. -// For oldObj, cache.DeletedFinalStateUnknown is handled and the -// object stored in it will be converted instead. -func As[T any](oldObj, newobj interface{}) (T, T, error) { - var oldTyped T - var newTyped T - var ok bool - if newobj != nil { - newTyped, ok = newobj.(T) - if !ok { - return oldTyped, newTyped, fmt.Errorf("expected %T, but got %T", newTyped, newobj) - } - } - - if oldObj != nil { - if realOldObj, ok := oldObj.(cache.DeletedFinalStateUnknown); ok { - oldObj = realOldObj.Obj - } - oldTyped, ok = oldObj.(T) - if !ok { - return oldTyped, newTyped, fmt.Errorf("expected %T, but got %T", oldTyped, oldObj) - } - } - return oldTyped, newTyped, nil -} - -// GetHostPorts returns the used host ports of pod containers and -// initContainers with restartPolicy: Always. -func GetHostPorts(pod *v1.Pod) []v1.ContainerPort { - var ports []v1.ContainerPort - if pod == nil { - return ports - } - - hostPort := func(p v1.ContainerPort) bool { - return p.HostPort > 0 - } - - for _, c := range pod.Spec.InitContainers { - // Only consider initContainers that will be running the entire - // duration of the Pod. - if c.RestartPolicy == nil || *c.RestartPolicy != v1.ContainerRestartPolicyAlways { - continue - } - for _, p := range c.Ports { - if !hostPort(p) { - continue - } - ports = append(ports, p) - } - } - for _, c := range pod.Spec.Containers { - for _, p := range c.Ports { - if !hostPort(p) { - continue - } - ports = append(ports, p) - } - } - return ports -} diff --git a/vendor/k8s.io/kubernetes/pkg/security/apparmor/OWNERS b/vendor/k8s.io/kubernetes/pkg/security/apparmor/OWNERS deleted file mode 100644 index 123e203f9..000000000 --- a/vendor/k8s.io/kubernetes/pkg/security/apparmor/OWNERS +++ /dev/null @@ -1,10 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - sig-node-approvers - - tallclair -reviewers: - - sig-node-reviewers - - tallclair -labels: - - sig/node diff --git a/vendor/k8s.io/kubernetes/pkg/security/apparmor/helpers.go b/vendor/k8s.io/kubernetes/pkg/security/apparmor/helpers.go deleted file mode 100644 index eeaa3955d..000000000 --- a/vendor/k8s.io/kubernetes/pkg/security/apparmor/helpers.go +++ /dev/null @@ -1,99 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package apparmor - -import ( - "strings" - - v1 "k8s.io/api/core/v1" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" -) - -// Checks whether app armor is required for the pod to run. AppArmor is considered required if any -// non-unconfined profiles are specified. -func isRequired(pod *v1.Pod) bool { - if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.AppArmorProfile != nil && - pod.Spec.SecurityContext.AppArmorProfile.Type != v1.AppArmorProfileTypeUnconfined { - return true - } - - inUse := !podutil.VisitContainers(&pod.Spec, podutil.AllContainers, func(c *v1.Container, _ podutil.ContainerType) bool { - if c.SecurityContext != nil && c.SecurityContext.AppArmorProfile != nil && - c.SecurityContext.AppArmorProfile.Type != v1.AppArmorProfileTypeUnconfined { - return false // is in use; short-circuit - } - return true - }) - if inUse { - return true - } - - for key, value := range pod.Annotations { - if strings.HasPrefix(key, v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix) { - return value != v1.DeprecatedAppArmorBetaProfileNameUnconfined - } - } - return false -} - -// GetProfileName returns the name of the profile to use with the container. -func GetProfile(pod *v1.Pod, container *v1.Container) *v1.AppArmorProfile { - if container.SecurityContext != nil && container.SecurityContext.AppArmorProfile != nil { - return container.SecurityContext.AppArmorProfile - } - - // Static pods may not have had annotations synced to fields, so fallback to annotations before - // the pod profile. - if profile := getProfileFromPodAnnotations(pod.Annotations, container.Name); profile != nil { - return profile - } - - if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.AppArmorProfile != nil { - return pod.Spec.SecurityContext.AppArmorProfile - } - - return nil -} - -// getProfileFromPodAnnotations gets the AppArmor profile to use with container from -// (deprecated) pod annotations. -func getProfileFromPodAnnotations(annotations map[string]string, containerName string) *v1.AppArmorProfile { - val, ok := annotations[v1.DeprecatedAppArmorBetaContainerAnnotationKeyPrefix+containerName] - if !ok { - return nil - } - - switch { - case val == v1.DeprecatedAppArmorBetaProfileRuntimeDefault: - return &v1.AppArmorProfile{Type: v1.AppArmorProfileTypeRuntimeDefault} - - case val == v1.DeprecatedAppArmorBetaProfileNameUnconfined: - return &v1.AppArmorProfile{Type: v1.AppArmorProfileTypeUnconfined} - - case strings.HasPrefix(val, v1.DeprecatedAppArmorBetaProfileNamePrefix): - // Note: an invalid empty localhost profile will be rejected by kubelet admission. - profileName := strings.TrimPrefix(val, v1.DeprecatedAppArmorBetaProfileNamePrefix) - return &v1.AppArmorProfile{ - Type: v1.AppArmorProfileTypeLocalhost, - LocalhostProfile: &profileName, - } - - default: - // Invalid annotation. - return nil - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go b/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go deleted file mode 100644 index 34113df71..000000000 --- a/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate.go +++ /dev/null @@ -1,101 +0,0 @@ -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package apparmor - -import ( - "errors" - "fmt" - "strings" - - v1 "k8s.io/api/core/v1" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" - "k8s.io/kubernetes/third_party/forked/libcontainer/apparmor" -) - -// Whether AppArmor should be disabled by default. -// Set to true if the wrong build tags are set (see validate_disabled.go). -var isDisabledBuild bool - -// Validator is a interface for validating that a pod with an AppArmor profile can be run by a Node. -type Validator interface { - Validate(pod *v1.Pod) error - ValidateHost() error -} - -// NewValidator is in order to find AppArmor FS -func NewValidator() Validator { - if err := validateHost(); err != nil { - return &validator{validateHostErr: err} - } - return &validator{} -} - -type validator struct { - validateHostErr error -} - -func (v *validator) Validate(pod *v1.Pod) error { - if !isRequired(pod) { - return nil - } - - if v.ValidateHost() != nil { - return v.validateHostErr - } - - var retErr error - podutil.VisitContainers(&pod.Spec, podutil.AllContainers, func(container *v1.Container, containerType podutil.ContainerType) bool { - profile := GetProfile(pod, container) - if profile == nil { - return true - } - - // TODO(#64841): This would ideally be part of validation.ValidateAppArmorProfileFormat, but - // that is called for API validation, and this is tightening validation. - if profile.Type == v1.AppArmorProfileTypeLocalhost { - if profile.LocalhostProfile == nil || strings.TrimSpace(*profile.LocalhostProfile) == "" { - retErr = fmt.Errorf("invalid empty AppArmor profile name: %q", profile) - return false - } - } - return true - }) - - return retErr -} - -// ValidateHost verifies that the host and runtime is capable of enforcing AppArmor profiles. -// Note, this is intentionally only check the host at kubelet startup and never re-evaluates the host -// as the expectation is that the kubelet restart will be needed to enable or disable AppArmor support. -func (v *validator) ValidateHost() error { - return v.validateHostErr -} - -// validateHost verifies that the host and runtime is capable of enforcing AppArmor profiles. -func validateHost() error { - // Check build support. - if isDisabledBuild { - return errors.New("binary not compiled for linux") - } - - // Check kernel support. - if !apparmor.IsEnabled() { - return errors.New("AppArmor is not enabled on the host") - } - - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go b/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go deleted file mode 100644 index 91a82c2ef..000000000 --- a/vendor/k8s.io/kubernetes/pkg/security/apparmor/validate_disabled.go +++ /dev/null @@ -1,25 +0,0 @@ -//go:build !linux -// +build !linux - -/* -Copyright 2016 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package apparmor - -func init() { - // If Kubernetes was not built for linux, apparmor is always disabled. - isDisabledBuild = true -} diff --git a/vendor/k8s.io/kubernetes/pkg/probe/OWNERS b/vendor/k8s.io/kubernetes/pkg/securitycontext/OWNERS similarity index 100% rename from vendor/k8s.io/kubernetes/pkg/probe/OWNERS rename to vendor/k8s.io/kubernetes/pkg/securitycontext/OWNERS diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go index ef1cd13a8..9eb7d581b 100644 --- a/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/accessors.go @@ -35,6 +35,7 @@ type PodSecurityContextAccessor interface { SeccompProfile() *api.SeccompProfile SupplementalGroups() []int64 FSGroup() *int64 + FSGroupChangePolicy() *api.PodFSGroupChangePolicy } // PodSecurityContextMutator allows reading and writing the values of a PodSecurityContext object @@ -52,6 +53,7 @@ type PodSecurityContextMutator interface { SetSeccompProfile(*api.SeccompProfile) SetSupplementalGroups([]int64) SetFSGroup(*int64) + SetFSGroupChangePolicy(*api.PodFSGroupChangePolicy) // PodSecurityContext returns the current PodSecurityContext object PodSecurityContext() *api.PodSecurityContext @@ -231,6 +233,23 @@ func (w *podSecurityContextWrapper) SetFSGroup(v *int64) { w.podSC.FSGroup = v } +func (w *podSecurityContextWrapper) FSGroupChangePolicy() *api.PodFSGroupChangePolicy { + if w.podSC == nil { + return nil + } + + return w.podSC.FSGroupChangePolicy +} + +func (w *podSecurityContextWrapper) SetFSGroupChangePolicy(v *api.PodFSGroupChangePolicy) { + if w.podSC == nil && v == nil { + return + } + + w.ensurePodSC() + w.podSC.FSGroupChangePolicy = v +} + // ContainerSecurityContextAccessor allows reading the values of a SecurityContext object type ContainerSecurityContextAccessor interface { Capabilities() *api.Capabilities diff --git a/vendor/k8s.io/kubernetes/pkg/securitycontext/util_linux.go b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_linux.go index bcaab4eb3..278c81ee2 100644 --- a/vendor/k8s.io/kubernetes/pkg/securitycontext/util_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/securitycontext/util_linux.go @@ -45,9 +45,9 @@ var possibleCPUsParsed = sync.OnceValue(func() (cpus []int) { return nil } - ranges := strings.Split(strings.TrimSpace(string(data)), ",") + ranges := strings.SplitSeq(strings.TrimSpace(string(data)), ",") - for _, r := range ranges { + for r := range ranges { if rStart, rEnd, ok := strings.Cut(r, "-"); !ok { cpu, err := strconv.Atoi(rStart) if err != nil { diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/defaultfs.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/defaultfs.go deleted file mode 100644 index 0dfd11fb4..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/defaultfs.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package filesystem - -import ( - "fmt" - "os" - "path/filepath" - "runtime" - "strings" - "time" -) - -// DefaultFs implements Filesystem using same-named functions from "os" and "io" -type DefaultFs struct { - root string -} - -var _ Filesystem = &DefaultFs{} - -// NewTempFs returns a fake Filesystem in temporary directory, useful for unit tests -func NewTempFs() Filesystem { - path, _ := os.MkdirTemp("", "tmpfs") - return &DefaultFs{ - root: path, - } -} - -func (fs *DefaultFs) prefix(path string) string { - if len(fs.root) == 0 { - return path - } - return filepath.Join(fs.root, path) -} - -// Stat via os.Stat -func (fs *DefaultFs) Stat(name string) (os.FileInfo, error) { - return os.Stat(fs.prefix(name)) -} - -// Create via os.Create -func (fs *DefaultFs) Create(name string) (File, error) { - file, err := os.Create(fs.prefix(name)) - if err != nil { - return nil, err - } - return &defaultFile{file}, nil -} - -// Rename via os.Rename -func (fs *DefaultFs) Rename(oldpath, newpath string) error { - if !strings.HasPrefix(oldpath, fs.root) { - oldpath = fs.prefix(oldpath) - } - if !strings.HasPrefix(newpath, fs.root) { - newpath = fs.prefix(newpath) - } - return os.Rename(oldpath, newpath) -} - -func (fs *DefaultFs) MkdirAll(path string, perm os.FileMode) error { - return MkdirAll(fs.prefix(path), perm) -} - -// MkdirAllWithPathCheck checks if path exists already. If not, it creates a directory -// named path, along with any necessary parents, and returns nil, or else returns an error. -// Permission bits perm (before umask) are used for all directories that -// MkdirAllWithPathCheck creates. -// If path is already a directory, MkdirAllWithPathCheck does nothing and returns nil. -// NOTE: In case of Windows NTFS, mount points are implemented as reparse-point -// (similar to symlink) and do not represent actual directory. Hence Directory existence -// check for windows NTFS will NOT check for dir, but for symlink presence. -func MkdirAllWithPathCheck(path string, perm os.FileMode) error { - if dir, err := os.Lstat(path); err == nil { - // If the path exists already, - // 1. for Unix/Linux OS, check if the path is directory. - // 2. for windows NTFS, check if the path is symlink instead of directory. - if dir.IsDir() || - (runtime.GOOS == "windows" && (dir.Mode()&os.ModeSymlink != 0 || dir.Mode()&os.ModeIrregular != 0)) { - return nil - } - return fmt.Errorf("path %v exists but is not a directory", path) - } - // If existence of path not known, attempt to create it. - if err := MkdirAll(path, perm); err != nil { - return err - } - return nil -} - -// Chtimes via os.Chtimes -func (fs *DefaultFs) Chtimes(name string, atime time.Time, mtime time.Time) error { - return os.Chtimes(fs.prefix(name), atime, mtime) -} - -// RemoveAll via os.RemoveAll -func (fs *DefaultFs) RemoveAll(path string) error { - return os.RemoveAll(fs.prefix(path)) -} - -// Remove via os.Remove -func (fs *DefaultFs) Remove(name string) error { - return os.Remove(fs.prefix(name)) -} - -// ReadFile via os.ReadFile -func (fs *DefaultFs) ReadFile(filename string) ([]byte, error) { - return os.ReadFile(fs.prefix(filename)) -} - -// TempDir via os.MkdirTemp -func (fs *DefaultFs) TempDir(dir, prefix string) (string, error) { - return os.MkdirTemp(fs.prefix(dir), prefix) -} - -// TempFile via os.CreateTemp -func (fs *DefaultFs) TempFile(dir, prefix string) (File, error) { - file, err := os.CreateTemp(fs.prefix(dir), prefix) - if err != nil { - return nil, err - } - return &defaultFile{file}, nil -} - -// ReadDir via os.ReadDir -func (fs *DefaultFs) ReadDir(dirname string) ([]os.DirEntry, error) { - return os.ReadDir(fs.prefix(dirname)) -} - -// Walk via filepath.Walk -func (fs *DefaultFs) Walk(root string, walkFn filepath.WalkFunc) error { - return filepath.Walk(fs.prefix(root), walkFn) -} - -// defaultFile implements File using same-named functions from "os" -type defaultFile struct { - file *os.File -} - -// Name via os.File.Name -func (file *defaultFile) Name() string { - return file.file.Name() -} - -// Write via os.File.Write -func (file *defaultFile) Write(b []byte) (n int, err error) { - return file.file.Write(b) -} - -// Sync via os.File.Sync -func (file *defaultFile) Sync() error { - return file.file.Sync() -} - -// Close via os.File.Close -func (file *defaultFile) Close() error { - return file.file.Close() -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/filesystem.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/filesystem.go deleted file mode 100644 index 6408e0fa8..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/filesystem.go +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package filesystem - -import ( - "os" - "path/filepath" - "time" -) - -// Filesystem is an interface that we can use to mock various filesystem operations -type Filesystem interface { - // from "os" - Stat(name string) (os.FileInfo, error) - Create(name string) (File, error) - Rename(oldpath, newpath string) error - MkdirAll(path string, perm os.FileMode) error - Chtimes(name string, atime time.Time, mtime time.Time) error - RemoveAll(path string) error - Remove(name string) error - - // from "os" - ReadFile(filename string) ([]byte, error) - TempDir(dir, prefix string) (string, error) - TempFile(dir, prefix string) (File, error) - ReadDir(dirname string) ([]os.DirEntry, error) - Walk(root string, walkFn filepath.WalkFunc) error -} - -// File is an interface that we can use to mock various filesystem operations typically -// accessed through the File object from the "os" package -type File interface { - // for now, the only os.File methods used are those below, add more as necessary - Name() string - Write(b []byte) (n int, err error) - Sync() error - Close() error -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go deleted file mode 100644 index d64fc37c7..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util.go +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package filesystem - -import ( - "path/filepath" -) - -// IsPathClean will replace slashes to Separator (which is OS-specific). -// This will make sure that all slashes are the same before comparing. -func IsPathClean(path string) bool { - return filepath.ToSlash(filepath.Clean(path)) == filepath.ToSlash(path) -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go deleted file mode 100644 index d27d2640f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_unix.go +++ /dev/null @@ -1,53 +0,0 @@ -//go:build freebsd || linux || darwin -// +build freebsd linux darwin - -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package filesystem - -import ( - "fmt" - "os" - "path/filepath" -) - -// IsUnixDomainSocket returns whether a given file is a AF_UNIX socket file -func IsUnixDomainSocket(filePath string) (bool, error) { - fi, err := os.Stat(filePath) - if err != nil { - return false, fmt.Errorf("stat file %s failed: %v", filePath, err) - } - if fi.Mode()&os.ModeSocket == 0 { - return false, nil - } - return true, nil -} - -// Chmod is the same as os.Chmod on Unix. -func Chmod(name string, mode os.FileMode) error { - return os.Chmod(name, mode) -} - -// MkdirAll is same as os.MkdirAll on Unix. -func MkdirAll(path string, perm os.FileMode) error { - return os.MkdirAll(path, perm) -} - -// IsAbs is same as filepath.IsAbs on Unix. -func IsAbs(path string) bool { - return filepath.IsAbs(path) -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go deleted file mode 100644 index 95616d34f..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/util_windows.go +++ /dev/null @@ -1,263 +0,0 @@ -//go:build windows -// +build windows - -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package filesystem - -import ( - "fmt" - "net" - "os" - "path/filepath" - "strings" - "time" - - "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/klog/v2" - - "golang.org/x/sys/windows" -) - -const ( - // Amount of time to wait between attempting to use a Unix domain socket. - // As detailed in https://github.com/kubernetes/kubernetes/issues/104584 - // the first attempt will most likely fail, hence the need to retry - socketDialRetryPeriod = 1 * time.Second - // Overall timeout value to dial a Unix domain socket, including retries - socketDialTimeout = 4 * time.Second -) - -// IsUnixDomainSocket returns whether a given file is a AF_UNIX socket file -// Note that due to the retry logic inside, it could take up to 4 seconds -// to determine whether or not the file path supplied is a Unix domain socket -func IsUnixDomainSocket(filePath string) (bool, error) { - // Note that querrying for the Reparse Points (https://docs.microsoft.com/en-us/windows/win32/fileio/reparse-points) - // for the file (using FSCTL_GET_REPARSE_POINT) and checking for reparse tag: reparseTagSocket - // does NOT work in 1809 if the socket file is created within a bind mounted directory by a container - // and the FSCTL is issued in the host by the kubelet. - - // If the file does not exist, it cannot be a Unix domain socket. - if info, err := os.Stat(filePath); os.IsNotExist(err) { - return false, fmt.Errorf("File %s not found. Err: %v", filePath, err) - } else if err == nil && info.Mode()&os.ModeSocket != 0 { // Use os.ModeSocket (introduced in Go 1.23 on Windows) - klog.V(6).InfoS("File identified as a Unix domain socket", "filePath", filePath) - return true, nil - } - klog.V(6).InfoS("Function IsUnixDomainSocket starts", "filePath", filePath) - // Due to the absence of golang support for os.ModeSocket in Windows (https://github.com/golang/go/issues/33357) - // we need to dial the file and check if we receive an error to determine if a file is Unix Domain Socket file. - // As detailed in https://github.com/kubernetes/kubernetes/issues/104584 we cannot rely - // on the Unix Domain socket working on the very first try, hence the potential need to - // dial multiple times - var lastSocketErr error - err := wait.PollImmediate(socketDialRetryPeriod, socketDialTimeout, - func() (bool, error) { - klog.V(6).InfoS("Dialing the socket", "filePath", filePath) - var c net.Conn - c, lastSocketErr = net.Dial("unix", filePath) - if lastSocketErr == nil { - c.Close() - klog.V(6).InfoS("Socket dialed successfully", "filePath", filePath) - return true, nil - } - klog.V(6).InfoS("Failed the current attempt to dial the socket, so pausing before retry", - "filePath", filePath, "err", lastSocketErr, "socketDialRetryPeriod", - socketDialRetryPeriod) - return false, nil - }) - - // PollImmediate will return "timed out waiting for the condition" if the function it - // invokes never returns true - if err != nil { - klog.V(2).InfoS("Failed all attempts to dial the socket so marking it as a non-Unix Domain socket. Last socket error along with the error from PollImmediate follow", - "filePath", filePath, "lastSocketErr", lastSocketErr, "err", err) - return false, nil - } - return true, nil -} - -// On Windows os.Mkdir all doesn't set any permissions so call the Chown function below to set -// permissions once the directory is created. -func MkdirAll(path string, perm os.FileMode) error { - klog.V(6).InfoS("Function MkdirAll starts", "path", path, "perm", perm) - if _, err := os.Stat(path); err == nil { - // Path already exists: nothing to do. - return nil - } else if !os.IsNotExist(err) { - return fmt.Errorf("error checking path %s: %w", path, err) - } - - err := os.MkdirAll(path, perm) - if err != nil { - return fmt.Errorf("error creating directory %s: %w", path, err) - } - - err = Chmod(path, perm) - if err != nil { - return fmt.Errorf("error setting permissions for directory %s: %w", path, err) - } - - return nil -} - -const ( - // These aren't defined in the syscall package for Windows :( - USER_READ = 0x100 - USER_WRITE = 0x80 - USER_EXECUTE = 0x40 - GROUP_READ = 0x20 - GROUP_WRITE = 0x10 - GROUP_EXECUTE = 0x8 - OTHERS_READ = 0x4 - OTHERS_WRITE = 0x2 - OTHERS_EXECUTE = 0x1 - USER_ALL = USER_READ | USER_WRITE | USER_EXECUTE - GROUP_ALL = GROUP_READ | GROUP_WRITE | GROUP_EXECUTE - OTHERS_ALL = OTHERS_READ | OTHERS_WRITE | OTHERS_EXECUTE -) - -// On Windows os.Chmod only sets the read-only flag on files, so we need to use Windows APIs to set the desired access on files / directories. -// The OWNER mode will set file permissions for the file owner SID, the GROUP mode will set file permissions for the file group SID, -// and the OTHERS mode will set file permissions for BUILTIN\Users. -// Please note that Windows containers can be run as one of two user accounts; ContainerUser or ContainerAdministrator. -// Containers run as ContainerAdministrator will inherit permissions from BUILTIN\Administrators, -// while containers run as ContainerUser will inherit permissions from BUILTIN\Users. -// Windows containers do not have the ability to run as a custom user account that is known to the host so the OTHERS group mode -// is used to grant / deny permissions of files on the hosts to the ContainerUser account. -func Chmod(path string, filemode os.FileMode) error { - klog.V(6).InfoS("Function Chmod starts", "path", path, "filemode", filemode) - // Get security descriptor for the file - sd, err := windows.GetNamedSecurityInfo( - path, - windows.SE_FILE_OBJECT, - windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION|windows.OWNER_SECURITY_INFORMATION|windows.GROUP_SECURITY_INFORMATION) - if err != nil { - return fmt.Errorf("Error getting security descriptor for file %s: %v", path, err) - } - - // Get owner SID from the security descriptor for assigning USER permissions - owner, _, err := sd.Owner() - if err != nil { - return fmt.Errorf("Error getting owner SID for file %s: %v", path, err) - } - ownerString := owner.String() - - // Get the group SID from the security descriptor for assigning GROUP permissions - group, _, err := sd.Group() - if err != nil { - return fmt.Errorf("Error getting group SID for file %s: %v", path, err) - } - groupString := group.String() - - mask := uint32(windows.ACCESS_MASK(filemode)) - - // Build a new Discretionary Access Control List (DACL) with the desired permissions using - //the Security Descriptor Definition Language (SDDL) format. - // https://learn.microsoft.com/windows/win32/secauthz/security-descriptor-definition-language - // the DACL is a list of Access Control Entries (ACEs) where each ACE represents the permissions (Allow or Deny) for a specific SID. - // Each ACE has the following format: - // (AceType;AceFlags;Rights;ObjectGuid;InheritObjectGuid;AccountSid) - // We can leave ObjectGuid and InheritObjectGuid empty for our purposes. - - dacl := "D:" - - // build the owner ACE - dacl += "(A;OICI;" - if mask&USER_ALL == USER_ALL { - dacl += "FA" - } else { - if mask&USER_READ == USER_READ { - dacl += "FR" - } - if mask&USER_WRITE == USER_WRITE { - dacl += "FW" - } - if mask&USER_EXECUTE == USER_EXECUTE { - dacl += "FX" - } - } - dacl += ";;;" + ownerString + ")" - - // Build the group ACE - dacl += "(A;OICI;" - if mask&GROUP_ALL == GROUP_ALL { - dacl += "FA" - } else { - if mask&GROUP_READ == GROUP_READ { - dacl += "FR" - } - if mask&GROUP_WRITE == GROUP_WRITE { - dacl += "FW" - } - if mask&GROUP_EXECUTE == GROUP_EXECUTE { - dacl += "FX" - } - } - dacl += ";;;" + groupString + ")" - - // Build the others ACE - dacl += "(A;OICI;" - if mask&OTHERS_ALL == OTHERS_ALL { - dacl += "FA" - } else { - if mask&OTHERS_READ == OTHERS_READ { - dacl += "FR" - } - if mask&OTHERS_WRITE == OTHERS_WRITE { - dacl += "FW" - } - if mask&OTHERS_EXECUTE == OTHERS_EXECUTE { - dacl += "FX" - } - } - dacl += ";;;BU)" - - klog.V(6).InfoS("Setting new DACL for path", "path", path, "dacl", dacl) - - // create a new security descriptor from the DACL string - newSD, err := windows.SecurityDescriptorFromString(dacl) - if err != nil { - return fmt.Errorf("Error creating new security descriptor from DACL string: %v", err) - } - - // get the DACL in binary format from the newly created security descriptor - newDACL, _, err := newSD.DACL() - if err != nil { - return fmt.Errorf("Error getting DACL from new security descriptor: %v", err) - } - - // Write the new security descriptor to the file - return windows.SetNamedSecurityInfo( - path, - windows.SE_FILE_OBJECT, - windows.DACL_SECURITY_INFORMATION|windows.PROTECTED_DACL_SECURITY_INFORMATION, - nil, // owner SID - nil, // group SID - newDACL, - nil) // SACL -} - -// IsAbs returns whether the given path is absolute or not. -// On Windows, filepath.IsAbs will not return True for paths prefixed with a slash, even -// though they can be used as absolute paths (https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats). -// -// WARN: It isn't safe to use this for API values which will propagate across systems (e.g. REST API values -// that get validated on Unix, persisted, then consumed by Windows, etc). -func IsAbs(path string) bool { - return filepath.IsAbs(path) || strings.HasPrefix(path, `\`) || strings.HasPrefix(path, `/`) -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go b/vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go deleted file mode 100644 index cbbc83985..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/filesystem/watcher.go +++ /dev/null @@ -1,216 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package filesystem - -import ( - "context" - "fmt" - "time" - - "github.com/fsnotify/fsnotify" -) - -// FSWatcher is a callback-based filesystem watcher abstraction for fsnotify. -type FSWatcher interface { - // Initializes the watcher with the given watch handlers. - // Called before all other methods. - Init(FSEventHandler, FSErrorHandler) error - - // Starts listening for events and errors. - // When an event or error occurs, the corresponding handler is called. - Run() - - // Add a filesystem path to watch - AddWatch(path string) error -} - -// FSEventHandler is called when a fsnotify event occurs. -type FSEventHandler func(event fsnotify.Event) - -// FSErrorHandler is called when a fsnotify error occurs. -type FSErrorHandler func(err error) - -type fsnotifyWatcher struct { - watcher *fsnotify.Watcher - eventHandler FSEventHandler - errorHandler FSErrorHandler -} - -var _ FSWatcher = &fsnotifyWatcher{} - -// NewFsnotifyWatcher returns an implementation of FSWatcher that continuously listens for -// fsnotify events and calls the event handler as soon as an event is received. -func NewFsnotifyWatcher() FSWatcher { - return &fsnotifyWatcher{} -} - -func (w *fsnotifyWatcher) AddWatch(path string) error { - return w.watcher.Add(path) -} - -func (w *fsnotifyWatcher) Init(eventHandler FSEventHandler, errorHandler FSErrorHandler) error { - var err error - w.watcher, err = fsnotify.NewWatcher() - if err != nil { - return err - } - - w.eventHandler = eventHandler - w.errorHandler = errorHandler - return nil -} - -func (w *fsnotifyWatcher) Run() { - go func() { - defer w.watcher.Close() - for { - select { - case event := <-w.watcher.Events: - if w.eventHandler != nil { - w.eventHandler(event) - } - case err := <-w.watcher.Errors: - if w.errorHandler != nil { - w.errorHandler(err) - } - } - } - }() -} - -type watchAddRemover interface { - Add(path string) error - Remove(path string) error -} -type noopWatcher struct{} - -func (noopWatcher) Add(path string) error { return nil } -func (noopWatcher) Remove(path string) error { return nil } - -// WatchUntil watches the specified path for changes and blocks until ctx is canceled. -// eventHandler() must be non-nil, and pollInterval must be greater than 0. -// eventHandler() is invoked whenever a change event is observed or pollInterval elapses. -// errorHandler() is invoked (if non-nil) whenever an error occurs initializing or watching the specified path. -// -// If path is a directory, only the directory and immediate children are watched. -// -// If path does not exist or cannot be watched, an error is passed to errorHandler() and eventHandler() is called at pollInterval. -// -// Multiple observed events may collapse to a single invocation of eventHandler(). -// -// eventHandler() is invoked immediately after successful initialization of the filesystem watch, -// in case the path changed concurrent with calling WatchUntil(). -func WatchUntil(ctx context.Context, pollInterval time.Duration, path string, eventHandler func(), errorHandler func(err error)) { - if pollInterval <= 0 { - panic(fmt.Errorf("pollInterval must be > 0")) - } - if eventHandler == nil { - panic(fmt.Errorf("eventHandler must be non-nil")) - } - if errorHandler == nil { - errorHandler = func(err error) {} - } - - // Initialize watcher, fall back to no-op - var ( - eventsCh chan fsnotify.Event - errorCh chan error - watcher watchAddRemover - ) - if w, err := fsnotify.NewWatcher(); err != nil { - errorHandler(fmt.Errorf("error creating file watcher, falling back to poll at interval %s: %w", pollInterval, err)) - watcher = noopWatcher{} - } else { - watcher = w - eventsCh = w.Events - errorCh = w.Errors - defer func() { - _ = w.Close() - }() - } - - // Initialize background poll - t := time.NewTicker(pollInterval) - defer t.Stop() - - attemptPeriodicRewatch := false - - // Start watching the path - if err := watcher.Add(path); err != nil { - errorHandler(err) - attemptPeriodicRewatch = true - } else { - // Invoke handle() at least once after successfully registering the listener, - // in case the file changed concurrent with calling WatchUntil. - eventHandler() - } - - for { - select { - case <-ctx.Done(): - return - - case <-t.C: - // Prioritize exiting if context is canceled - if ctx.Err() != nil { - return - } - - // Try to re-establish the watcher if we previously got a watch error - if attemptPeriodicRewatch { - _ = watcher.Remove(path) - if err := watcher.Add(path); err != nil { - errorHandler(err) - } else { - attemptPeriodicRewatch = false - } - } - - // Handle - eventHandler() - - case e := <-eventsCh: - // Prioritize exiting if context is canceled - if ctx.Err() != nil { - return - } - - // Try to re-establish the watcher for events which dropped the existing watch - if e.Name == path && (e.Has(fsnotify.Remove) || e.Has(fsnotify.Rename)) { - _ = watcher.Remove(path) - if err := watcher.Add(path); err != nil { - errorHandler(err) - attemptPeriodicRewatch = true - } - } - - // Handle - eventHandler() - - case err := <-errorCh: - // Prioritize exiting if context is canceled - if ctx.Err() != nil { - return - } - - // If the error occurs in response to calling watcher.Add, re-adding here could hot-loop. - // The periodic poll will attempt to re-establish the watch. - errorHandler(err) - attemptPeriodicRewatch = true - } - } -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/kernel/OWNERS b/vendor/k8s.io/kubernetes/pkg/util/kernel/OWNERS deleted file mode 100644 index 9437a5858..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/kernel/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -reviewers: - - sig-network-reviewers - - sig-node-reviewers -approvers: - - sig-network-approvers - - sig-node-approvers diff --git a/vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go b/vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go deleted file mode 100644 index 1467f6c22..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/kernel/constants.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package kernel - -// IPLocalReservedPortsNamespacedKernelVersion is the kernel version in which net.ipv4.ip_local_reserved_ports was namespaced(netns). -// (ref: https://github.com/torvalds/linux/commit/122ff243f5f104194750ecbc76d5946dd1eec934) -const IPLocalReservedPortsNamespacedKernelVersion = "3.16" - -// IPVSConnReuseModeMinSupportedKernelVersion is the minium kernel version supporting net.ipv4.vs.conn_reuse_mode. -// (ref: https://github.com/torvalds/linux/commit/d752c364571743d696c2a54a449ce77550c35ac5) -const IPVSConnReuseModeMinSupportedKernelVersion = "4.1" - -// TCPKeepAliveTimeNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_keepalive_time was namespaced(netns). -// (ref: https://github.com/torvalds/linux/commit/13b287e8d1cad951634389f85b8c9b816bd3bb1e) -const TCPKeepAliveTimeNamespacedKernelVersion = "4.5" - -// TCPKeepAliveIntervalNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_keepalive_intvl was namespaced(netns). -// (ref: https://github.com/torvalds/linux/commit/b840d15d39128d08ed4486085e5507d2617b9ae1) -const TCPKeepAliveIntervalNamespacedKernelVersion = "4.5" - -// TCPKeepAliveProbesNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_keepalive_probes was namespaced(netns). -// (ref: https://github.com/torvalds/linux/commit/9bd6861bd4326e3afd3f14a9ec8a723771fb20bb) -const TCPKeepAliveProbesNamespacedKernelVersion = "4.5" - -// TCPFinTimeoutNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_fin_timeout was namespaced(netns). -// (ref: https://github.com/torvalds/linux/commit/1e579caa18b96f9eb18f4f5416658cd15f37c062) -const TCPFinTimeoutNamespacedKernelVersion = "4.6" - -// IPVSConnReuseModeFixedKernelVersion is the kernel version in which net.ipv4.vs.conn_reuse_mode was fixed. -// (ref: https://github.com/torvalds/linux/commit/35dfb013149f74c2be1ff9c78f14e6a3cd1539d1) -const IPVSConnReuseModeFixedKernelVersion = "5.9" - -const TmpfsNoswapSupportKernelVersion = "6.4" - -// NFTablesKubeProxyKernelVersion is the lowest kernel version kube-proxy supports using -// nftables mode with by default. This is not directly related to any specific kernel -// commit; see https://issues.k8s.io/122743#issuecomment-1893922424 -const NFTablesKubeProxyKernelVersion = "5.13" - -// TCPReceiveMemoryNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_rmem was namespaced(netns). -// (ref: https://github.com/torvalds/linux/commit/356d1833b638bd465672aefeb71def3ab93fc17d) -const TCPReceiveMemoryNamespacedKernelVersion = "4.15" - -// TCPTransmitMemoryNamespacedKernelVersion is the kernel version in which net.ipv4.tcp_wmem was namespaced(netns). -// (ref: https://github.com/torvalds/linux/commit/356d1833b638bd465672aefeb71def3ab93fc17d) -const TCPTransmitMemoryNamespacedKernelVersion = "4.15" diff --git a/vendor/k8s.io/kubernetes/pkg/util/kernel/version.go b/vendor/k8s.io/kubernetes/pkg/util/kernel/version.go deleted file mode 100644 index 79f0bf9a5..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/kernel/version.go +++ /dev/null @@ -1,48 +0,0 @@ -/* -Copyright 2023 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package kernel - -import ( - "fmt" - "os" - "strings" - - "k8s.io/apimachinery/pkg/util/version" -) - -type readFileFunc func(string) ([]byte, error) - -// GetVersion returns currently running kernel version. -func GetVersion() (*version.Version, error) { - return getVersion(os.ReadFile) -} - -// getVersion reads os release file from the give readFile function. -func getVersion(readFile readFileFunc) (*version.Version, error) { - kernelVersionFile := "/proc/sys/kernel/osrelease" - fileContent, err := readFile(kernelVersionFile) - if err != nil { - return nil, fmt.Errorf("failed to read os-release file: %s", err.Error()) - } - - kernelVersion, err := version.ParseGeneric(strings.TrimSpace(string(fileContent))) - if err != nil { - return nil, fmt.Errorf("failed to parse kernel version: %s", err.Error()) - } - - return kernelVersion, nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/oom/doc.go b/vendor/k8s.io/kubernetes/pkg/util/oom/doc.go deleted file mode 100644 index 9825a53f2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/oom/doc.go +++ /dev/null @@ -1,18 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package oom implements utility functions relating to out of memory management. -package oom diff --git a/vendor/k8s.io/kubernetes/pkg/util/oom/oom.go b/vendor/k8s.io/kubernetes/pkg/util/oom/oom.go deleted file mode 100644 index a5b1ea0ff..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/oom/oom.go +++ /dev/null @@ -1,26 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package oom - -// This is a struct instead of an interface to allow injection of process ID listers and -// applying OOM score in tests. -// TODO: make this an interface, and inject a mock ioutil struct for testing. -type OOMAdjuster struct { - pidLister func(cgroupName string) ([]int, error) - ApplyOOMScoreAdj func(pid int, oomScoreAdj int) error - ApplyOOMScoreAdjContainer func(cgroupName string, oomScoreAdj, maxTries int) error -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_fake.go b/vendor/k8s.io/kubernetes/pkg/util/oom/oom_fake.go deleted file mode 100644 index 2712c5d0b..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_fake.go +++ /dev/null @@ -1,35 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package oom - -type FakeOOMAdjuster struct{} - -func NewFakeOOMAdjuster() *OOMAdjuster { - return &OOMAdjuster{ - pidLister: func(cgroupName string) ([]int, error) { return make([]int, 0), nil }, - ApplyOOMScoreAdj: fakeApplyOOMScoreAdj, - ApplyOOMScoreAdjContainer: fakeApplyOOMScoreAdjContainer, - } -} - -func fakeApplyOOMScoreAdj(pid int, oomScoreAdj int) error { - return nil -} - -func fakeApplyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { - return nil -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go b/vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go deleted file mode 100644 index 380967f9c..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_linux.go +++ /dev/null @@ -1,130 +0,0 @@ -//go:build linux -// +build linux - -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package oom - -import ( - "fmt" - "os" - "path" - "path/filepath" - "strconv" - "time" - - cmutil "k8s.io/kubernetes/pkg/kubelet/cm/util" - - "k8s.io/klog/v2" -) - -func NewOOMAdjuster() *OOMAdjuster { - oomAdjuster := &OOMAdjuster{ - pidLister: getPids, - ApplyOOMScoreAdj: applyOOMScoreAdj, - } - oomAdjuster.ApplyOOMScoreAdjContainer = oomAdjuster.applyOOMScoreAdjContainer - return oomAdjuster -} - -func getPids(cgroupName string) ([]int, error) { - return cmutil.GetPids(filepath.Join("/", cgroupName)) -} - -// Writes 'value' to /proc//oom_score_adj. PID = 0 means self -// Returns os.ErrNotExist if the `pid` does not exist. -func applyOOMScoreAdj(pid int, oomScoreAdj int) error { - if pid < 0 { - return fmt.Errorf("invalid PID %d specified for oom_score_adj", pid) - } - - var pidStr string - if pid == 0 { - pidStr = "self" - } else { - pidStr = strconv.Itoa(pid) - } - - maxTries := 2 - oomScoreAdjPath := path.Join("/proc", pidStr, "oom_score_adj") - value := strconv.Itoa(oomScoreAdj) - klog.V(4).Infof("attempting to set %q to %q", oomScoreAdjPath, value) - var err error - for i := 0; i < maxTries; i++ { - err = os.WriteFile(oomScoreAdjPath, []byte(value), 0700) - if err != nil { - if os.IsNotExist(err) { - klog.V(2).Infof("%q does not exist", oomScoreAdjPath) - return os.ErrNotExist - } - - klog.V(3).Info(err) - time.Sleep(100 * time.Millisecond) - continue - } - return nil - } - if err != nil { - klog.V(2).Infof("failed to set %q to %q: %v", oomScoreAdjPath, value, err) - } - return err -} - -// Writes 'value' to /proc//oom_score_adj for all processes in cgroup cgroupName. -// Keeps trying to write until the process list of the cgroup stabilizes, or until maxTries tries. -func (oomAdjuster *OOMAdjuster) applyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { - adjustedProcessSet := make(map[int]bool) - for i := 0; i < maxTries; i++ { - continueAdjusting := false - pidList, err := oomAdjuster.pidLister(cgroupName) - if err != nil { - if os.IsNotExist(err) { - // Nothing to do since the container doesn't exist anymore. - return os.ErrNotExist - } - continueAdjusting = true - klog.V(10).Infof("Error getting process list for cgroup %s: %+v", cgroupName, err) - } else if len(pidList) == 0 { - klog.V(10).Infof("Pid list is empty") - continueAdjusting = true - } else { - for _, pid := range pidList { - if !adjustedProcessSet[pid] { - klog.V(10).Infof("pid %d needs to be set", pid) - if err = oomAdjuster.ApplyOOMScoreAdj(pid, oomScoreAdj); err == nil { - adjustedProcessSet[pid] = true - } else if err == os.ErrNotExist { - continue - } else { - klog.V(10).Infof("cannot adjust oom score for pid %d - %v", pid, err) - continueAdjusting = true - } - // Processes can come and go while we try to apply oom score adjust value. So ignore errors here. - } - } - } - if !continueAdjusting { - return nil - } - // There's a slight race. A process might have forked just before we write its OOM score adjust. - // The fork might copy the parent process's old OOM score, then this function might execute and - // update the parent's OOM score, but the forked process id might not be reflected in cgroup.procs - // for a short amount of time. So this function might return without changing the forked process's - // OOM score. Very unlikely race, so ignoring this for now. - } - return fmt.Errorf("exceeded maxTries, some processes might not have desired OOM score") -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go b/vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go deleted file mode 100644 index 1e4b926e2..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/oom/oom_unsupported.go +++ /dev/null @@ -1,41 +0,0 @@ -//go:build !linux -// +build !linux - -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package oom - -import ( - "errors" -) - -var unsupportedErr = errors.New("setting OOM scores is unsupported in this build") - -func NewOOMAdjuster() *OOMAdjuster { - return &OOMAdjuster{ - ApplyOOMScoreAdj: unsupportedApplyOOMScoreAdj, - ApplyOOMScoreAdjContainer: unsupportedApplyOOMScoreAdjContainer, - } -} - -func unsupportedApplyOOMScoreAdj(pid int, oomScoreAdj int) error { - return unsupportedErr -} - -func unsupportedApplyOOMScoreAdjContainer(cgroupName string, oomScoreAdj, maxTries int) error { - return unsupportedErr -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/pod/pod.go b/vendor/k8s.io/kubernetes/pkg/util/pod/pod.go deleted file mode 100644 index 8caa21007..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/pod/pod.go +++ /dev/null @@ -1,81 +0,0 @@ -/* -Copyright 2018 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package pod - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - - v1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/strategicpatch" - clientset "k8s.io/client-go/kubernetes" - podutil "k8s.io/kubernetes/pkg/api/v1/pod" -) - -// PatchPodStatus patches pod status. It returns true and avoids an update if the patch contains no changes. -func PatchPodStatus(ctx context.Context, c clientset.Interface, namespace, name string, uid types.UID, oldPodStatus, newPodStatus v1.PodStatus) (*v1.Pod, []byte, bool, error) { - patchBytes, unchanged, err := preparePatchBytesForPodStatus(namespace, name, uid, oldPodStatus, newPodStatus) - if err != nil { - return nil, nil, false, err - } - if unchanged { - return nil, patchBytes, true, nil - } - - updatedPod, err := c.CoreV1().Pods(namespace).Patch(ctx, name, types.StrategicMergePatchType, patchBytes, metav1.PatchOptions{}, "status") - if err != nil { - return nil, nil, false, fmt.Errorf("failed to patch status %q for pod %q/%q: %v", patchBytes, namespace, name, err) - } - return updatedPod, patchBytes, false, nil -} - -func preparePatchBytesForPodStatus(namespace, name string, uid types.UID, oldPodStatus, newPodStatus v1.PodStatus) ([]byte, bool, error) { - oldData, err := json.Marshal(v1.Pod{ - Status: oldPodStatus, - }) - if err != nil { - return nil, false, fmt.Errorf("failed to Marshal oldData for pod %q/%q: %v", namespace, name, err) - } - - newData, err := json.Marshal(v1.Pod{ - ObjectMeta: metav1.ObjectMeta{UID: uid}, // only put the uid in the new object to ensure it appears in the patch as a precondition - Status: newPodStatus, - }) - if err != nil { - return nil, false, fmt.Errorf("failed to Marshal newData for pod %q/%q: %v", namespace, name, err) - } - - patchBytes, err := strategicpatch.CreateTwoWayMergePatch(oldData, newData, v1.Pod{}) - if err != nil { - return nil, false, fmt.Errorf("failed to CreateTwoWayMergePatch for pod %q/%q: %v", namespace, name, err) - } - return patchBytes, bytes.Equal(patchBytes, []byte(fmt.Sprintf(`{"metadata":{"uid":%q}}`, uid))), nil -} - -// ReplaceOrAppendPodCondition replaces the first pod condition with equal type or appends if there is none -func ReplaceOrAppendPodCondition(conditions []v1.PodCondition, condition *v1.PodCondition) []v1.PodCondition { - if i, _ := podutil.GetPodConditionFromList(conditions, condition.Type); i >= 0 { - conditions[i] = *condition - } else { - conditions = append(conditions, *condition) - } - return conditions -} diff --git a/vendor/k8s.io/kubernetes/pkg/util/slice/slice.go b/vendor/k8s.io/kubernetes/pkg/util/slice/slice.go deleted file mode 100644 index 872fbdcad..000000000 --- a/vendor/k8s.io/kubernetes/pkg/util/slice/slice.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright 2015 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package slice provides utility methods for common operations on slices. -package slice - -import ( - "sort" -) - -// CopyStrings copies the contents of the specified string slice -// into a new slice. -func CopyStrings(s []string) []string { - if s == nil { - return nil - } - c := make([]string, len(s)) - copy(c, s) - return c -} - -// SortStrings sorts the specified string slice in place. It returns the same -// slice that was provided in order to facilitate method chaining. -func SortStrings(s []string) []string { - sort.Strings(s) - return s -} - -// ContainsString checks if a given slice of strings contains the provided string. -// If a modifier func is provided, it is called with the slice item before the comparation. -func ContainsString(slice []string, s string, modifier func(s string) string) bool { - for _, item := range slice { - if item == s { - return true - } - if modifier != nil && modifier(item) == s { - return true - } - } - return false -} - -// RemoveString returns a newly created []string that contains all items from slice that -// are not equal to s and modifier(s) in case modifier func is provided. -func RemoveString(slice []string, s string, modifier func(s string) string) []string { - newSlice := make([]string, 0) - for _, item := range slice { - if item == s { - continue - } - if modifier != nil && modifier(item) == s { - continue - } - newSlice = append(newSlice, item) - } - if len(newSlice) == 0 { - // Sanitize for unit tests so we don't need to distinguish empty array - // and nil. - newSlice = nil - } - return newSlice -} diff --git a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go index acfff76d3..24b661493 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/plugins.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/plugins.go @@ -17,15 +17,14 @@ limitations under the License. package volume import ( + "context" "errors" "fmt" - "net" "strings" "sync" "k8s.io/klog/v2" "k8s.io/mount-utils" - "k8s.io/utils/exec" authenticationv1 "k8s.io/api/authentication/v1" v1 "k8s.io/api/core/v1" @@ -174,8 +173,6 @@ type VolumePlugin interface { ConstructVolumeSpec(volumeName, volumePath string) (ReconstructedVolume, error) // SupportsMountOption returns true if volume plugins supports Mount options - // Specifying mount options in a volume plugin that doesn't support - // user specified mount options will result in error creating persistent volumes SupportsMountOption() bool // SupportsSELinuxContextMount returns true if volume plugins supports @@ -234,7 +231,7 @@ type AttachableVolumePlugin interface { NewDetacher() (Detacher, error) // CanAttach tests if provided volume spec is attachable CanAttach(spec *Spec) (bool, error) - VerifyExhaustedResource(spec *Spec, nodeName types.NodeName) + VerifyExhaustedResource(spec *Spec) bool } // DeviceMountableVolumePlugin is an extended interface of VolumePlugin and is used @@ -316,6 +313,9 @@ type KubeletVolumeHost interface { // Returns trust anchors from the ClusterTrustBundles selected by signer // name and label selector. GetTrustAnchorsBySigner(signerName string, labelSelector *metav1.LabelSelector, allowMissing bool) ([]byte, error) + + // Returns the credential bundle for the specified podCertificate projected volume source. + GetPodCertificateCredentialBundle(ctx context.Context, namespace, podName, podUID, volumeName string, sourceIndex int) ([]byte, []byte, error) } // CSIDriverVolumeHost is a volume host that has access to CSIDriverLister @@ -388,14 +388,11 @@ type VolumeHost interface { NewWrapperUnmounter(volName string, spec Spec, podUID types.UID) (Unmounter, error) // Get mounter interface. - GetMounter(pluginName string) mount.Interface + GetMounter() mount.Interface // Returns the hostname of the host kubelet is running on GetHostName() string - // Returns host IP or nil in the case of error. - GetHostIP() (net.IP, error) - // Returns node allocatable. GetNodeAllocatable() (v1.ResourceList, error) @@ -409,9 +406,6 @@ type VolumeHost interface { DeleteServiceAccountTokenFunc() func(podUID types.UID) - // Returns an interface that should be used to execute any utilities in volume plugins - GetExec(pluginName string) exec.Interface - // Returns the labels on the node GetNodeLabels() (map[string]string, error) diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/attach_limit.go b/vendor/k8s.io/kubernetes/pkg/volume/util/attach_limit.go index 943357b65..4249a6be4 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/attach_limit.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/attach_limit.go @@ -25,28 +25,6 @@ import ( // shared between volume package and scheduler const ( - // EBSVolumeLimitKey resource name that will store volume limits for EBS - EBSVolumeLimitKey = "attachable-volumes-aws-ebs" - // EBSNitroLimitRegex finds nitro instance types with different limit than EBS defaults - EBSNitroLimitRegex = "^[cmr]5.*|t3|z1d" - // DefaultMaxEBSVolumes is the limit for volumes attached to an instance. - // Amazon recommends no more than 40; the system root volume uses at least one. - // See http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/volume_limits.html#linux-specific-volume-limits - DefaultMaxEBSVolumes = 39 - // DefaultMaxEBSNitroVolumeLimit is default EBS volume limit on m5 and c5 instances - DefaultMaxEBSNitroVolumeLimit = 25 - // AzureVolumeLimitKey stores resource name that will store volume limits for Azure - AzureVolumeLimitKey = "attachable-volumes-azure-disk" - // GCEVolumeLimitKey stores resource name that will store volume limits for GCE node - GCEVolumeLimitKey = "attachable-volumes-gce-pd" - - // CinderVolumeLimitKey contains Volume limit key for Cinder - CinderVolumeLimitKey = "attachable-volumes-cinder" - // DefaultMaxCinderVolumes defines the maximum number of PD Volumes for Cinder - // For Openstack we are keeping this to a high enough value so as depending on backend - // cluster admins can configure it. - DefaultMaxCinderVolumes = 256 - // CSIAttachLimitPrefix defines prefix used for CSI volumes CSIAttachLimitPrefix = "attachable-volumes-csi-" diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go index 599f22097..189db6ed8 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/resize_util.go @@ -34,6 +34,7 @@ import ( "k8s.io/kubernetes/pkg/volume" volumetypes "k8s.io/kubernetes/pkg/volume/util/types" "k8s.io/mount-utils" + "k8s.io/utils/exec" ) var ( @@ -456,7 +457,7 @@ func mergeStorageAllocatedResources(pvc *v1.PersistentVolumeClaim, size resource } // GenericResizeFS : call generic filesystem resizer for plugins that don't have any special filesystem resize requirements -func GenericResizeFS(host volume.VolumeHost, pluginName, devicePath, deviceMountPath string) (bool, error) { - resizer := mount.NewResizeFs(host.GetExec(pluginName)) +func GenericResizeFS(host volume.VolumeHost, devicePath, deviceMountPath string) (bool, error) { + resizer := mount.NewResizeFs(exec.New()) return resizer.Resize(devicePath, deviceMountPath) } diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/types/types.go b/vendor/k8s.io/kubernetes/pkg/volume/util/types/types.go index 316962f8f..333421323 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/types/types.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/types/types.go @@ -25,6 +25,10 @@ import ( "k8s.io/mount-utils" ) +var ( + NodeExpansionNotRequired = "volume.kubernetes.io/node-expansion-not-required" +) + // UniquePodName defines the type to key pods off of type UniquePodName types.UID diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go index 0173902eb..4c77d5a9b 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/util.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/util.go @@ -333,14 +333,6 @@ func SplitUniqueName(uniqueName v1.UniqueVolumeName) (string, string, error) { return pluginName, components[2], nil } -// NewSafeFormatAndMountFromHost creates a new SafeFormatAndMount with Mounter -// and Exec taken from given VolumeHost. -func NewSafeFormatAndMountFromHost(pluginName string, host volume.VolumeHost) *mount.SafeFormatAndMount { - mounter := host.GetMounter(pluginName) - exec := host.GetExec(pluginName) - return &mount.SafeFormatAndMount{Interface: mounter, Exec: exec} -} - // GetVolumeMode retrieves VolumeMode from pv. // If the volume doesn't have PersistentVolume, it's an inline volume, // should return volumeMode as filesystem to keep existing behavior. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler.go b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler.go index fa0b24a18..1f468410b 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/util/volumepathhandler/volume_path_handler.go @@ -103,12 +103,12 @@ func (v VolumePathHandler) MapDevice(devicePath string, mapPath string, linkName } if bindMount { - return mapBindMountDevice(v, devicePath, mapPath, linkName) + return mapBindMountDevice(devicePath, mapPath, linkName) } - return mapSymlinkDevice(v, devicePath, mapPath, linkName) + return mapSymlinkDevice(devicePath, mapPath, linkName) } -func mapBindMountDevice(v VolumePathHandler, devicePath string, mapPath string, linkName string) error { +func mapBindMountDevice(devicePath string, mapPath string, linkName string) error { // Check bind mount exists linkPath := filepath.Join(mapPath, string(linkName)) @@ -146,7 +146,7 @@ func mapBindMountDevice(v VolumePathHandler, devicePath string, mapPath string, return nil } -func mapSymlinkDevice(v VolumePathHandler, devicePath string, mapPath string, linkName string) error { +func mapSymlinkDevice(devicePath string, mapPath string, linkName string) error { // Remove old symbolic link(or file) then create new one. // This should be done because current symbolic link is // stale across node reboot. diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume.go b/vendor/k8s.io/kubernetes/pkg/volume/volume.go index f5f933e0c..36814591c 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume.go @@ -134,6 +134,15 @@ type MounterArgs struct { DesiredSize *resource.Quantity SELinuxLabel string Recorder record.EventRecorder + + // Optional interface that will be used to change the ownership of the volume, if specified. + // mainly used by unit tests + VolumeOwnershipApplicator VolumeOwnershipChanger +} + +type VolumeOwnershipChanger interface { + AddProgressNotifier(pod *v1.Pod, recorder record.EventRecorder) VolumeOwnershipChanger + ChangePermissions() error } type VolumeOwnership struct { diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go index 9d023abfa..0df840cde 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume_linux.go @@ -51,7 +51,7 @@ var ( ) // NewVolumeOwnership returns an interface that can be used to recursively change volume permissions and ownership -func NewVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) *VolumeOwnership { +func NewVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) VolumeOwnershipChanger { vo := &VolumeOwnership{ mounter: mounter, dir: dir, @@ -63,7 +63,7 @@ func NewVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChan return vo } -func (vo *VolumeOwnership) AddProgressNotifier(pod *v1.Pod, recorder record.EventRecorder) *VolumeOwnership { +func (vo *VolumeOwnership) AddProgressNotifier(pod *v1.Pod, recorder record.EventRecorder) VolumeOwnershipChanger { vo.pod = pod vo.recorder = recorder return vo diff --git a/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go b/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go index cfedeaa32..ef46dac61 100644 --- a/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go +++ b/vendor/k8s.io/kubernetes/pkg/volume/volume_unsupported.go @@ -26,11 +26,11 @@ import ( ) // NewVolumeOwnership returns an interface that can be used to recursively change volume permissions and ownership -func NewVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) *VolumeOwnership { - return nil +func NewVolumeOwnership(mounter Mounter, dir string, fsGroup *int64, fsGroupChangePolicy *v1.PodFSGroupChangePolicy, completeFunc func(types.CompleteFuncParam)) VolumeOwnershipChanger { + return &VolumeOwnership{} } -func (vo *VolumeOwnership) AddProgressNotifier(pod *v1.Pod, recorder record.EventRecorder) *VolumeOwnership { +func (vo *VolumeOwnership) AddProgressNotifier(pod *v1.Pod, recorder record.EventRecorder) VolumeOwnershipChanger { return vo } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go index 7e6875b49..aed88d518 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/debug/resource_usage_gatherer.go @@ -41,6 +41,7 @@ import ( "k8s.io/kubernetes/test/e2e/framework" e2essh "k8s.io/kubernetes/test/e2e/framework/ssh" + "k8s.io/utils/ptr" ) // ResourceConstraint is a struct to hold constraints. @@ -259,10 +260,10 @@ func getOneTimeResourceUsageOnNode( return &ContainerResourceUsage{ Name: name, Timestamp: newStats.StartTime.Time, - CPUUsageInCores: float64(removeUint64Ptr(newStats.CPU.UsageNanoCores)) / 1000000000, - MemoryUsageInBytes: removeUint64Ptr(newStats.Memory.UsageBytes), - MemoryWorkingSetInBytes: removeUint64Ptr(newStats.Memory.WorkingSetBytes), - MemoryRSSInBytes: removeUint64Ptr(newStats.Memory.RSSBytes), + CPUUsageInCores: float64(ptr.Deref(newStats.CPU.UsageNanoCores, 0)) / 1000000000, + MemoryUsageInBytes: ptr.Deref(newStats.Memory.UsageBytes, 0), + MemoryWorkingSetInBytes: ptr.Deref(newStats.Memory.WorkingSetBytes, 0), + MemoryRSSInBytes: ptr.Deref(newStats.Memory.RSSBytes, 0), CPUInterval: 0, } } @@ -313,13 +314,6 @@ func getStatsSummary(c clientset.Interface, nodeName string) (*kubeletstatsv1alp return &summary, nil } -func removeUint64Ptr(ptr *uint64) uint64 { - if ptr == nil { - return 0 - } - return *ptr -} - func (w *resourceGatherWorker) gather(ctx context.Context, initialSleep time.Duration) { defer utilruntime.HandleCrash() defer w.wg.Done() diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go index ff08e25b4..74df75a63 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/framework.go @@ -544,6 +544,11 @@ func (f *Framework) ClientConfig() *rest.Config { return ret } +// SetClientConfig allows setting or updating the REST config in the Framework instance. +func (f *Framework) SetClientConfig(config *rest.Config) { + f.clientConfig = rest.CopyConfig(config) +} + // KubeUser is a struct for managing kubernetes user info. type KubeUser struct { Name string `yaml:"name"` diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/get.go b/vendor/k8s.io/kubernetes/test/e2e/framework/get.go index 1e1a83856..f941a7bb9 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/get.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/get.go @@ -20,6 +20,7 @@ import ( "context" "errors" "fmt" + "io" "time" "github.com/onsi/gomega" @@ -103,6 +104,7 @@ func ShouldRetry(err error) (retry bool, retryAfter time.Duration) { if apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) || apierrors.IsServiceUnavailable(err) || + errors.Is(err, io.EOF) || errors.As(err, &transientError{}) { return true, 0 } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go index ccc045ba7..06d6974ad 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/ginkgowrapper.go @@ -343,7 +343,7 @@ func recordTextBug(location types.CodeLocation, message string) { RecordBug(Bug{FileName: location.FileName, LineNumber: location.LineNumber, Message: message}) } -// WithEnvironment specifies that a certain test or group of tests only works +// WithFeature specifies that a certain test or group of tests only works // with a feature available. The return value must be passed as additional // argument to [framework.It], [framework.Describe], [framework.Context]. // @@ -444,7 +444,7 @@ func withEnvironment(name Environment) interface{} { return newLabel("Environment", string(name)) } -// WithConformace specifies that a certain test or group of tests must pass in +// WithConformance specifies that a certain test or group of tests must pass in // all conformant Kubernetes clusters. The return value must be passed as // additional argument to [framework.It], [framework.Describe], // [framework.Context]. @@ -515,9 +515,10 @@ func withSerial() interface{} { return newLabel("Serial") } -// WithSlow specifies that a certain test or group of tests must not run in -// parallel with other tests. The return value must be passed as additional -// argument to [framework.It], [framework.Describe], [framework.Context]. +// WithSlow specifies that a certain test, or each test within a group of +// tests, is slow (is expected to take longer than 5 minutes to run in CI). +// The return value must be passed as additional argument to [framework.It], +// [framework.Describe], [framework.Context]. func WithSlow() interface{} { return withSlow() } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go index e33acb7d1..8c8faaa1f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/kubectl/builder.go @@ -37,8 +37,13 @@ import ( // KubectlBuilder is used to build, customize and execute a kubectl Command. // Add more functions to customize the builder as needed. type KubectlBuilder struct { - cmd *exec.Cmd - timeout <-chan time.Time + cmd *exec.Cmd + // appendEnv contains only AppendEnv(...) values and NOT os.Environ() + // logging os.Environ is ~redundant and noisy + // logging the env we modified is important to understand what we're running + // versus the defaults + appendedEnv []string + timeout <-chan time.Time } // NewKubectlCommand returns a KubectlBuilder for running kubectl. @@ -55,6 +60,7 @@ func (b *KubectlBuilder) AppendEnv(env []string) *KubectlBuilder { b.cmd.Env = os.Environ() } b.cmd.Env = append(b.cmd.Env, env...) + b.appendedEnv = append(b.appendedEnv, env...) return b } @@ -118,7 +124,11 @@ func (b KubectlBuilder) ExecWithFullOutput() (string, string, error) { cmd := b.cmd cmd.Stdout, cmd.Stderr = &stdout, &stderr - framework.Logf("Running '%s %s'", cmd.Path, strings.Join(cmd.Args[1:], " ")) // skip arg[0] as it is printed separately + if len(b.appendedEnv) > 0 { + framework.Logf("Running '%s %s %s'", strings.Join(b.appendedEnv, " "), cmd.Path, strings.Join(cmd.Args[1:], " ")) // skip arg[0] as it is printed separately + } else { + framework.Logf("Running '%s %s'", cmd.Path, strings.Join(cmd.Args[1:], " ")) // skip arg[0] as it is printed separately + } if err := cmd.Start(); err != nil { return "", "", fmt.Errorf("error starting %v:\nCommand stdout:\n%v\nstderr:\n%v\nerror:\n%v", cmd, cmd.Stdout, cmd.Stderr, err) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go index 360862d34..04cf7f8a9 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/delete.go @@ -26,6 +26,7 @@ import ( v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/errors" clientset "k8s.io/client-go/kubernetes" "k8s.io/kubernetes/test/e2e/framework" ) @@ -44,7 +45,7 @@ func DeletePodOrFail(ctx context.Context, c clientset.Interface, ns, name string return } - expectNoError(err, "failed to delete pod %s in namespace %s", name, ns) + framework.ExpectNoErrorWithOffset(1, err, "failed to delete pod %s in namespace %s", name, ns) } // DeletePodWithWait deletes the passed-in pod and waits for the pod to be terminated. Resilient to the pod @@ -56,6 +57,21 @@ func DeletePodWithWait(ctx context.Context, c clientset.Interface, pod *v1.Pod) return DeletePodWithWaitByName(ctx, c, pod.GetName(), pod.GetNamespace()) } +// DeletePodsWithWait deletes the passed-in pods, waits for them to be terminated, and reports any deletion errors that occur. +func DeletePodsWithWait(ctx context.Context, c clientset.Interface, pods []*v1.Pod) { + var delErrs []error + for _, testPod := range pods { + delErr := c.CoreV1().Pods(testPod.Namespace).Delete(ctx, testPod.Name, metav1.DeleteOptions{}) + if delErr != nil && !apierrors.IsNotFound(delErr) { + delErrs = append(delErrs, delErr) + } + } + framework.ExpectNoError(errors.NewAggregate(delErrs), "while deleting pods") + for _, testPod := range pods { + framework.ExpectNoError(WaitForPodNotFoundInNamespace(ctx, c, testPod.Name, testPod.Namespace, PodDeleteTimeout)) + } +} + // DeletePodWithWaitByName deletes the named and namespaced pod and waits for the pod to be terminated. Resilient to the pod // not existing. func DeletePodWithWaitByName(ctx context.Context, c clientset.Interface, podName, podNamespace string) error { diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go index 3494ef5a8..664eae425 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/pod_client.go @@ -130,6 +130,19 @@ func (c *PodClient) Create(ctx context.Context, pod *v1.Pod) *v1.Pod { } +// TryCreate attempts to create a new pod according to the provided specification. +// This function is designed to return an error to the caller if pod creation fails. +func (c *PodClient) TryCreate(ctx context.Context, pod *v1.Pod) (*v1.Pod, error) { + ginkgo.GinkgoHelper() + c.mungeSpec(pod) + c.setOwnerAnnotation(pod) + p, err := c.PodInterface.Create(ctx, pod, metav1.CreateOptions{}) + if err != nil { + return nil, fmt.Errorf("error creating pod %s/%s: %w", pod.Namespace, pod.Name, err) + } + return p, nil +} + // CreateSync creates a new pod according to the framework specifications, and wait for it to start and be running and ready. func (c *PodClient) CreateSync(ctx context.Context, pod *v1.Pod) *v1.Pod { ginkgo.GinkgoHelper() diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resize.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resize.go deleted file mode 100644 index af8d43ac3..000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resize.go +++ /dev/null @@ -1,537 +0,0 @@ -/* -Copyright 2024 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package pod - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "strconv" - "strings" - - v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - utilerrors "k8s.io/apimachinery/pkg/util/errors" - helpers "k8s.io/component-helpers/resource" - "k8s.io/kubectl/pkg/util/podutils" - kubecm "k8s.io/kubernetes/pkg/kubelet/cm" - kubeqos "k8s.io/kubernetes/pkg/kubelet/qos" - "k8s.io/kubernetes/test/e2e/framework" - imageutils "k8s.io/kubernetes/test/utils/image" - - "github.com/onsi/ginkgo/v2" - "github.com/onsi/gomega" -) - -const ( - CgroupCPUPeriod string = "/sys/fs/cgroup/cpu/cpu.cfs_period_us" - CgroupCPUShares string = "/sys/fs/cgroup/cpu/cpu.shares" - CgroupCPUQuota string = "/sys/fs/cgroup/cpu/cpu.cfs_quota_us" - CgroupMemLimit string = "/sys/fs/cgroup/memory/memory.limit_in_bytes" - Cgroupv2MemLimit string = "/sys/fs/cgroup/memory.max" - Cgroupv2MemRequest string = "/sys/fs/cgroup/memory.min" - Cgroupv2CPULimit string = "/sys/fs/cgroup/cpu.max" - Cgroupv2CPURequest string = "/sys/fs/cgroup/cpu.weight" - CPUPeriod string = "100000" - MinContainerRuntimeVersion string = "1.6.9" -) - -var ( - podOnCgroupv2Node *bool -) - -type ContainerResources struct { - CPUReq string - CPULim string - MemReq string - MemLim string - EphStorReq string - EphStorLim string - ExtendedResourceReq string - ExtendedResourceLim string -} - -func (cr *ContainerResources) ResourceRequirements() *v1.ResourceRequirements { - if cr == nil { - return nil - } - - var lim, req v1.ResourceList - if cr.CPULim != "" || cr.MemLim != "" || cr.EphStorLim != "" { - lim = make(v1.ResourceList) - } - if cr.CPUReq != "" || cr.MemReq != "" || cr.EphStorReq != "" { - req = make(v1.ResourceList) - } - if cr.CPULim != "" { - lim[v1.ResourceCPU] = resource.MustParse(cr.CPULim) - } - if cr.MemLim != "" { - lim[v1.ResourceMemory] = resource.MustParse(cr.MemLim) - } - if cr.EphStorLim != "" { - lim[v1.ResourceEphemeralStorage] = resource.MustParse(cr.EphStorLim) - } - if cr.CPUReq != "" { - req[v1.ResourceCPU] = resource.MustParse(cr.CPUReq) - } - if cr.MemReq != "" { - req[v1.ResourceMemory] = resource.MustParse(cr.MemReq) - } - if cr.EphStorReq != "" { - req[v1.ResourceEphemeralStorage] = resource.MustParse(cr.EphStorReq) - } - return &v1.ResourceRequirements{Limits: lim, Requests: req} -} - -type ResizableContainerInfo struct { - Name string - Resources *ContainerResources - CPUPolicy *v1.ResourceResizeRestartPolicy - MemPolicy *v1.ResourceResizeRestartPolicy - RestartCount int32 - RestartPolicy v1.ContainerRestartPolicy - InitCtr bool -} - -type containerPatch struct { - Name string `json:"name"` - Resources struct { - Requests struct { - CPU string `json:"cpu,omitempty"` - Memory string `json:"memory,omitempty"` - EphStor string `json:"ephemeral-storage,omitempty"` - } `json:"requests"` - Limits struct { - CPU string `json:"cpu,omitempty"` - Memory string `json:"memory,omitempty"` - EphStor string `json:"ephemeral-storage,omitempty"` - } `json:"limits"` - } `json:"resources"` -} - -type patchSpec struct { - Spec struct { - Containers []containerPatch `json:"containers"` - } `json:"spec"` -} - -func getTestResourceInfo(tcInfo ResizableContainerInfo) (res v1.ResourceRequirements, resizePol []v1.ContainerResizePolicy) { - if tcInfo.Resources != nil { - res = *tcInfo.Resources.ResourceRequirements() - } - if tcInfo.CPUPolicy != nil { - cpuPol := v1.ContainerResizePolicy{ResourceName: v1.ResourceCPU, RestartPolicy: *tcInfo.CPUPolicy} - resizePol = append(resizePol, cpuPol) - } - if tcInfo.MemPolicy != nil { - memPol := v1.ContainerResizePolicy{ResourceName: v1.ResourceMemory, RestartPolicy: *tcInfo.MemPolicy} - resizePol = append(resizePol, memPol) - } - return res, resizePol -} - -func makeResizableContainer(tcInfo ResizableContainerInfo) v1.Container { - cmd := "grep Cpus_allowed_list /proc/self/status | cut -f2 && sleep 1d" - res, resizePol := getTestResourceInfo(tcInfo) - - tc := v1.Container{ - Name: tcInfo.Name, - Image: imageutils.GetE2EImage(imageutils.BusyBox), - Command: []string{"/bin/sh"}, - Args: []string{"-c", cmd}, - Resources: res, - ResizePolicy: resizePol, - } - if tcInfo.RestartPolicy != "" { - tc.RestartPolicy = &tcInfo.RestartPolicy - } - - return tc -} - -func MakePodWithResizableContainers(ns, name, timeStamp string, tcInfo []ResizableContainerInfo) *v1.Pod { - testInitContainers, testContainers := separateContainers(tcInfo) - - minGracePeriodSeconds := int64(0) - pod := &v1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Namespace: ns, - Labels: map[string]string{ - "time": timeStamp, - }, - }, - Spec: v1.PodSpec{ - OS: &v1.PodOS{Name: v1.Linux}, - InitContainers: testInitContainers, - Containers: testContainers, - RestartPolicy: v1.RestartPolicyOnFailure, - TerminationGracePeriodSeconds: &minGracePeriodSeconds, - }, - } - return pod -} - -// separateContainers splits the input into initContainers and normal containers. -func separateContainers(tcInfo []ResizableContainerInfo) ([]v1.Container, []v1.Container) { - var initContainers, containers []v1.Container - - for _, ci := range tcInfo { - tc := makeResizableContainer(ci) - if ci.InitCtr { - initContainers = append(initContainers, tc) - } else { - containers = append(containers, tc) - } - } - - return initContainers, containers -} - -// separateContainerStatuses splits the input into initContainerStatuses and containerStatuses. -func separateContainerStatuses(tcInfo []ResizableContainerInfo) ([]v1.ContainerStatus, []v1.ContainerStatus) { - var containerStatuses, initContainerStatuses []v1.ContainerStatus - - for _, ci := range tcInfo { - ctrStatus := v1.ContainerStatus{ - Name: ci.Name, - RestartCount: ci.RestartCount, - } - if ci.InitCtr { - initContainerStatuses = append(initContainerStatuses, ctrStatus) - } else { - containerStatuses = append(containerStatuses, ctrStatus) - } - } - - return initContainerStatuses, containerStatuses -} - -func VerifyPodResizePolicy(gotPod *v1.Pod, wantInfo []ResizableContainerInfo) { - ginkgo.GinkgoHelper() - - gotCtrs := append(append([]v1.Container{}, gotPod.Spec.Containers...), gotPod.Spec.InitContainers...) - var wantCtrs []v1.Container - for _, ci := range wantInfo { - wantCtrs = append(wantCtrs, makeResizableContainer(ci)) - } - gomega.Expect(gotCtrs).To(gomega.HaveLen(len(wantCtrs)), "number of containers in pod spec should match") - for _, wantCtr := range wantCtrs { - for _, gotCtr := range gotCtrs { - if wantCtr.Name != gotCtr.Name { - continue - } - gomega.Expect(v1.Container{Name: gotCtr.Name, ResizePolicy: gotCtr.ResizePolicy}).To(gomega.Equal(v1.Container{Name: wantCtr.Name, ResizePolicy: wantCtr.ResizePolicy})) - } - } -} - -func VerifyPodResources(gotPod *v1.Pod, wantInfo []ResizableContainerInfo) { - ginkgo.GinkgoHelper() - - gotCtrs := append(append([]v1.Container{}, gotPod.Spec.Containers...), gotPod.Spec.InitContainers...) - var wantCtrs []v1.Container - for _, ci := range wantInfo { - wantCtrs = append(wantCtrs, makeResizableContainer(ci)) - } - gomega.Expect(gotCtrs).To(gomega.HaveLen(len(wantCtrs)), "number of containers in pod spec should match") - for _, wantCtr := range wantCtrs { - for _, gotCtr := range gotCtrs { - if wantCtr.Name != gotCtr.Name { - continue - } - gomega.Expect(v1.Container{Name: gotCtr.Name, Resources: gotCtr.Resources}).To(gomega.Equal(v1.Container{Name: wantCtr.Name, Resources: wantCtr.Resources})) - } - } -} - -func VerifyPodStatusResources(gotPod *v1.Pod, wantInfo []ResizableContainerInfo) error { - ginkgo.GinkgoHelper() - - wantInitCtrs, wantCtrs := separateContainers(wantInfo) - var errs []error - if err := verifyPodContainersStatusResources(gotPod.Status.InitContainerStatuses, wantInitCtrs); err != nil { - errs = append(errs, err) - } - if err := verifyPodContainersStatusResources(gotPod.Status.ContainerStatuses, wantCtrs); err != nil { - errs = append(errs, err) - } - - return utilerrors.NewAggregate(errs) -} - -func verifyPodContainersStatusResources(gotCtrStatuses []v1.ContainerStatus, wantCtrs []v1.Container) error { - ginkgo.GinkgoHelper() - - var errs []error - if len(gotCtrStatuses) != len(wantCtrs) { - return fmt.Errorf("expectation length mismatch: got %d statuses, want %d", - len(gotCtrStatuses), len(wantCtrs)) - } - for i, wantCtr := range wantCtrs { - gotCtrStatus := gotCtrStatuses[i] - if gotCtrStatus.Name != wantCtr.Name { - errs = append(errs, fmt.Errorf("container status %d name %q != expected name %q", i, gotCtrStatus.Name, wantCtr.Name)) - continue - } - if err := framework.Gomega().Expect(*gotCtrStatus.Resources).To(gomega.Equal(wantCtr.Resources)); err != nil { - errs = append(errs, fmt.Errorf("container[%s] status resources mismatch: %w", wantCtr.Name, err)) - } - } - - return utilerrors.NewAggregate(errs) -} - -func VerifyPodContainersCgroupValues(ctx context.Context, f *framework.Framework, pod *v1.Pod, tcInfo []ResizableContainerInfo) error { - ginkgo.GinkgoHelper() - if podOnCgroupv2Node == nil { - value := IsPodOnCgroupv2Node(f, pod) - podOnCgroupv2Node = &value - } - cgroupMemLimit := Cgroupv2MemLimit - cgroupCPULimit := Cgroupv2CPULimit - cgroupCPURequest := Cgroupv2CPURequest - if !*podOnCgroupv2Node { - cgroupMemLimit = CgroupMemLimit - cgroupCPULimit = CgroupCPUQuota - cgroupCPURequest = CgroupCPUShares - } - - var errs []error - for _, ci := range tcInfo { - if ci.Resources == nil { - continue - } - tc := makeResizableContainer(ci) - if tc.Resources.Limits != nil || tc.Resources.Requests != nil { - var expectedCPUShares int64 - var expectedMemLimitString string - expectedMemLimitInBytes := tc.Resources.Limits.Memory().Value() - cpuRequest := tc.Resources.Requests.Cpu() - cpuLimit := tc.Resources.Limits.Cpu() - if cpuRequest.IsZero() && !cpuLimit.IsZero() { - expectedCPUShares = int64(kubecm.MilliCPUToShares(cpuLimit.MilliValue())) - } else { - expectedCPUShares = int64(kubecm.MilliCPUToShares(cpuRequest.MilliValue())) - } - - expectedCPULimits := GetCPULimitCgroupExpectations(cpuLimit) - expectedMemLimitString = strconv.FormatInt(expectedMemLimitInBytes, 10) - if *podOnCgroupv2Node { - if expectedMemLimitString == "0" { - expectedMemLimitString = "max" - } - // convert cgroup v1 cpu.shares value to cgroup v2 cpu.weight value - // https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2254-cgroup-v2#phase-1-convert-from-cgroups-v1-settings-to-v2 - expectedCPUShares = int64(1 + ((expectedCPUShares-2)*9999)/262142) - } - - if expectedMemLimitString != "0" { - errs = append(errs, VerifyCgroupValue(f, pod, ci.Name, cgroupMemLimit, expectedMemLimitString)) - } - errs = append(errs, VerifyCgroupValue(f, pod, ci.Name, cgroupCPULimit, expectedCPULimits...)) - errs = append(errs, VerifyCgroupValue(f, pod, ci.Name, cgroupCPURequest, strconv.FormatInt(expectedCPUShares, 10))) - // TODO(vinaykul,InPlacePodVerticalScaling): Verify oom_score_adj when runc adds support for updating it - // See https://github.com/opencontainers/runc/pull/4669 - } - } - return utilerrors.NewAggregate(errs) -} - -func verifyPodRestarts(f *framework.Framework, pod *v1.Pod, wantInfo []ResizableContainerInfo) error { - ginkgo.GinkgoHelper() - - initCtrStatuses, ctrStatuses := separateContainerStatuses(wantInfo) - errs := []error{} - if err := verifyContainerRestarts(f, pod, pod.Status.InitContainerStatuses, initCtrStatuses); err != nil { - errs = append(errs, err) - } - if err := verifyContainerRestarts(f, pod, pod.Status.ContainerStatuses, ctrStatuses); err != nil { - errs = append(errs, err) - } - - return utilerrors.NewAggregate(errs) -} - -func verifyContainerRestarts(f *framework.Framework, pod *v1.Pod, gotStatuses []v1.ContainerStatus, wantStatuses []v1.ContainerStatus) error { - ginkgo.GinkgoHelper() - - if len(gotStatuses) != len(wantStatuses) { - return fmt.Errorf("expectation length mismatch: got %d statuses, want %d", - len(gotStatuses), len(wantStatuses)) - } - - errs := []error{} - for i, gotStatus := range gotStatuses { - if gotStatus.RestartCount != wantStatuses[i].RestartCount { - errs = append(errs, fmt.Errorf("unexpected number of restarts for container %s: got %d, want %d", gotStatus.Name, gotStatus.RestartCount, wantStatuses[i].RestartCount)) - } else if gotStatus.RestartCount > 0 { - err := verifyOomScoreAdj(f, pod, gotStatus.Name) - if err != nil { - errs = append(errs, err) - } - } - } - return utilerrors.NewAggregate(errs) -} - -func verifyOomScoreAdj(f *framework.Framework, pod *v1.Pod, containerName string) error { - container := FindContainerInPod(pod, containerName) - if container == nil { - return fmt.Errorf("failed to find container %s in pod %s", containerName, pod.Name) - } - - node, err := f.ClientSet.CoreV1().Nodes().Get(context.Background(), pod.Spec.NodeName, metav1.GetOptions{}) - if err != nil { - return err - } - - nodeMemoryCapacity := node.Status.Capacity[v1.ResourceMemory] - oomScoreAdj := kubeqos.GetContainerOOMScoreAdjust(pod, container, int64(nodeMemoryCapacity.Value())) - expectedOomScoreAdj := strconv.FormatInt(int64(oomScoreAdj), 10) - - return VerifyOomScoreAdjValue(f, pod, container.Name, expectedOomScoreAdj) -} - -func WaitForPodResizeActuation(ctx context.Context, f *framework.Framework, podClient *PodClient, pod *v1.Pod, expectedContainers []ResizableContainerInfo) *v1.Pod { - ginkgo.GinkgoHelper() - // Wait for resize to complete. - - framework.ExpectNoError(framework.Gomega(). - Eventually(ctx, framework.RetryNotFound(framework.GetObject(f.ClientSet.CoreV1().Pods(pod.Namespace).Get, pod.Name, metav1.GetOptions{}))). - WithTimeout(f.Timeouts.PodStart). - Should(framework.MakeMatcher(func(pod *v1.Pod) (func() string, error) { - if helpers.IsPodResizeInfeasible(pod) { - // This is a terminal resize state - return func() string { - return "resize is infeasible" - }, nil - } - // TODO: Replace this check with a combination of checking the status.observedGeneration - // and the resize status when available. - if resourceErrs := VerifyPodStatusResources(pod, expectedContainers); resourceErrs != nil { - return func() string { - return fmt.Sprintf("container status resources don't match expected: %v", formatErrors(resourceErrs)) - }, nil - } - // Wait for kubelet to clear the resize status conditions. - for _, c := range pod.Status.Conditions { - if c.Type == v1.PodResizePending || c.Type == v1.PodResizeInProgress { - return func() string { - return fmt.Sprintf("resize status %v is still present in the pod status", c) - }, nil - } - } - // Wait for the pod to be ready. - if !podutils.IsPodReady(pod) { - return func() string { return "pod is not ready" }, nil - } - return nil, nil - })), - ) - - resizedPod, err := framework.GetObject(podClient.Get, pod.Name, metav1.GetOptions{})(ctx) - framework.ExpectNoError(err, "failed to get resized pod") - return resizedPod -} - -func ExpectPodResized(ctx context.Context, f *framework.Framework, resizedPod *v1.Pod, expectedContainers []ResizableContainerInfo) { - ginkgo.GinkgoHelper() - - // Verify Pod Containers Cgroup Values - var errs []error - if cgroupErrs := VerifyPodContainersCgroupValues(ctx, f, resizedPod, expectedContainers); cgroupErrs != nil { - errs = append(errs, fmt.Errorf("container cgroup values don't match expected: %w", formatErrors(cgroupErrs))) - } - if resourceErrs := VerifyPodStatusResources(resizedPod, expectedContainers); resourceErrs != nil { - errs = append(errs, fmt.Errorf("container status resources don't match expected: %w", formatErrors(resourceErrs))) - } - if restartErrs := verifyPodRestarts(f, resizedPod, expectedContainers); restartErrs != nil { - errs = append(errs, fmt.Errorf("container restart counts don't match expected: %w", formatErrors(restartErrs))) - } - - // Verify Pod Resize conditions are empty. - for _, condition := range resizedPod.Status.Conditions { - if condition.Type == v1.PodResizeInProgress || condition.Type == v1.PodResizePending { - errs = append(errs, fmt.Errorf("unexpected resize condition type %s found in pod status", condition.Type)) - } - } - - if len(errs) > 0 { - resizedPod.ManagedFields = nil // Suppress managed fields in error output. - framework.ExpectNoError(formatErrors(utilerrors.NewAggregate(errs)), - "Verifying pod resources resize state. Pod: %s", framework.PrettyPrintJSON(resizedPod)) - } -} - -// ResizeContainerPatch generates a patch string to resize the pod container. -func ResizeContainerPatch(containers []ResizableContainerInfo) (string, error) { - var patch patchSpec - - for _, container := range containers { - var cPatch containerPatch - cPatch.Name = container.Name - cPatch.Resources.Requests.CPU = container.Resources.CPUReq - cPatch.Resources.Requests.Memory = container.Resources.MemReq - cPatch.Resources.Limits.CPU = container.Resources.CPULim - cPatch.Resources.Limits.Memory = container.Resources.MemLim - - patch.Spec.Containers = append(patch.Spec.Containers, cPatch) - } - - patchBytes, err := json.Marshal(patch) - if err != nil { - return "", err - } - - return string(patchBytes), nil -} - -// UpdateExpectedContainerRestarts updates the RestartCounts in expectedContainers by -// adding them to the existing RestartCounts in the containerStatuses of the provided pod. -// This reduces the flakiness of the RestartCount assertions by grabbing the current -// restart count right before the resize operation, and verify the expected increment (0 or 1) -// rather than the absolute count. -func UpdateExpectedContainerRestarts(ctx context.Context, pod *v1.Pod, expectedContainers []ResizableContainerInfo) []ResizableContainerInfo { - initialRestarts := make(map[string]int32) - newExpectedContainers := []ResizableContainerInfo{} - for _, ctr := range pod.Status.ContainerStatuses { - initialRestarts[ctr.Name] = ctr.RestartCount - } - for i, ctr := range expectedContainers { - newExpectedContainers = append(newExpectedContainers, expectedContainers[i]) - newExpectedContainers[i].RestartCount += initialRestarts[ctr.Name] - } - return newExpectedContainers -} - -func formatErrors(err error) error { - // Put each error on a new line for readability. - var agg utilerrors.Aggregate - if !errors.As(err, &agg) { - return err - } - - errStrings := make([]string, len(agg.Errors())) - for i, err := range agg.Errors() { - errStrings[i] = err.Error() - } - return fmt.Errorf("[\n%s\n]", strings.Join(errStrings, ",\n")) -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go index 6dc039587..ca2b63a13 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/resource.go @@ -26,7 +26,6 @@ import ( "time" "github.com/onsi/ginkgo/v2" - "github.com/onsi/gomega" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -43,22 +42,6 @@ import ( // have their logs fetched. const LabelLogOnPodFailure = "log-on-pod-failure" -// TODO: Move to its own subpkg. -// expectNoError checks if "err" is set, and if so, fails assertion while logging the error. -func expectNoError(err error, explain ...interface{}) { - expectNoErrorWithOffset(1, err, explain...) -} - -// TODO: Move to its own subpkg. -// expectNoErrorWithOffset checks if "err" is set, and if so, fails assertion while logging the error at "offset" levels above its caller -// (for example, for call chain f -> g -> expectNoErrorWithOffset(1, ...) error would be logged for "f"). -func expectNoErrorWithOffset(offset int, err error, explain ...interface{}) { - if err != nil { - framework.Logf("Unexpected error occurred: %v", err) - } - gomega.ExpectWithOffset(1+offset, err).NotTo(gomega.HaveOccurred(), explain...) -} - // PodsCreatedByLabel returns a created pod list matched by the given label. func PodsCreatedByLabel(ctx context.Context, c clientset.Interface, ns, name string, replicas int32, label labels.Selector) (*v1.PodList, error) { timeout := 2 * time.Minute @@ -364,9 +347,9 @@ func CreateExecPodOrFail(ctx context.Context, client clientset.Interface, ns, ge tweak(pod) } execPod, err := client.CoreV1().Pods(ns).Create(ctx, pod, metav1.CreateOptions{}) - expectNoError(err, "failed to create new exec pod in namespace: %s", ns) + framework.ExpectNoErrorWithOffset(1, err, "failed to create new exec pod in namespace: %s", ns) err = WaitForPodNameRunningInNamespace(ctx, client, execPod.Name, execPod.Namespace) - expectNoError(err, "failed to create new exec pod in namespace: %s", ns) + framework.ExpectNoErrorWithOffset(1, err, "failed to create new exec pod in namespace: %s", ns) return execPod } diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go index db7106e86..b1fd25bed 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pod/utils.go @@ -18,20 +18,16 @@ package pod import ( "fmt" - "strconv" - "strings" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" v1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - kubecm "k8s.io/kubernetes/pkg/kubelet/cm" "k8s.io/kubernetes/test/e2e/framework" imageutils "k8s.io/kubernetes/test/utils/image" psaapi "k8s.io/pod-security-admission/api" psapolicy "k8s.io/pod-security-admission/policy" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" ) // This command runs an infinite loop, sleeping for 1 second in each iteration. @@ -66,6 +62,9 @@ func GetDefaultTestImage() string { // due to the issue of #https://github.com/kubernetes-sigs/windows-testing/pull/35. // If the node OS is linux, return busybox image func GetDefaultTestImageID() imageutils.ImageID { + if framework.NodeOSDistroIs("windows") { + return GetTestImageID(imageutils.Agnhost) + } return GetTestImageID(imageutils.BusyBox) } @@ -96,7 +95,7 @@ func GetDefaultNonRootUser() *int64 { if framework.NodeOSDistroIs("windows") { return nil } - return pointer.Int64(DefaultNonRootUser) + return ptr.To[int64](DefaultNonRootUser) } // GeneratePodSecurityContext generates the corresponding pod security context with the given inputs @@ -123,11 +122,11 @@ func GenerateContainerSecurityContext(level psaapi.Level) *v1.SecurityContext { switch level { case psaapi.LevelBaseline: return &v1.SecurityContext{ - Privileged: pointer.Bool(false), + Privileged: ptr.To(false), } case psaapi.LevelPrivileged: return &v1.SecurityContext{ - Privileged: pointer.Bool(true), + Privileged: ptr.To(true), } case psaapi.LevelRestricted: return GetRestrictedContainerSecurityContext() @@ -158,14 +157,14 @@ const DefaultNonRootUserName = "ContainerUser" // Tests that require a specific user ID should override this. func GetRestrictedPodSecurityContext() *v1.PodSecurityContext { psc := &v1.PodSecurityContext{ - RunAsNonRoot: pointer.Bool(true), + RunAsNonRoot: ptr.To(true), RunAsUser: GetDefaultNonRootUser(), SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}, } if framework.NodeOSDistroIs("windows") { psc.WindowsOptions = &v1.WindowsSecurityContextOptions{} - psc.WindowsOptions.RunAsUserName = pointer.String(DefaultNonRootUserName) + psc.WindowsOptions.RunAsUserName = ptr.To(DefaultNonRootUserName) } return psc @@ -174,7 +173,7 @@ func GetRestrictedPodSecurityContext() *v1.PodSecurityContext { // GetRestrictedContainerSecurityContext returns a minimal restricted container security context. func GetRestrictedContainerSecurityContext() *v1.SecurityContext { return &v1.SecurityContext{ - AllowPrivilegeEscalation: pointer.Bool(false), + AllowPrivilegeEscalation: ptr.To(false), Capabilities: &v1.Capabilities{Drop: []v1.Capability{"ALL"}}, } } @@ -198,7 +197,7 @@ func MixinRestrictedPodSecurity(pod *v1.Pod) error { pod.Spec.SecurityContext = GetRestrictedPodSecurityContext() } else { if pod.Spec.SecurityContext.RunAsNonRoot == nil { - pod.Spec.SecurityContext.RunAsNonRoot = pointer.Bool(true) + pod.Spec.SecurityContext.RunAsNonRoot = ptr.To(true) } if pod.Spec.SecurityContext.RunAsUser == nil { pod.Spec.SecurityContext.RunAsUser = GetDefaultNonRootUser() @@ -208,7 +207,7 @@ func MixinRestrictedPodSecurity(pod *v1.Pod) error { } if framework.NodeOSDistroIs("windows") && pod.Spec.SecurityContext.WindowsOptions == nil { pod.Spec.SecurityContext.WindowsOptions = &v1.WindowsSecurityContextOptions{} - pod.Spec.SecurityContext.WindowsOptions.RunAsUserName = pointer.String(DefaultNonRootUserName) + pod.Spec.SecurityContext.WindowsOptions.RunAsUserName = ptr.To(DefaultNonRootUserName) } } for i := range pod.Spec.Containers { @@ -238,7 +237,7 @@ func mixinRestrictedContainerSecurityContext(container *v1.Container) { container.SecurityContext = GetRestrictedContainerSecurityContext() } else { if container.SecurityContext.AllowPrivilegeEscalation == nil { - container.SecurityContext.AllowPrivilegeEscalation = pointer.Bool(false) + container.SecurityContext.AllowPrivilegeEscalation = ptr.To(false) } if container.SecurityContext.Capabilities == nil { container.SecurityContext.Capabilities = &v1.Capabilities{} @@ -293,86 +292,3 @@ func FindContainerStatusInPod(pod *v1.Pod, containerName string) *v1.ContainerSt } return nil } - -// VerifyCgroupValue verifies that the given cgroup path has the expected value in -// the specified container of the pod. It execs into the container to retrieve the -// cgroup value, and ensures that the retrieved cgroup value is equivalent to at -// least one of the values in expectedCgValues. -func VerifyCgroupValue(f *framework.Framework, pod *v1.Pod, cName, cgPath string, expectedCgValues ...string) error { - cmd := fmt.Sprintf("head -n 1 %s", cgPath) - framework.Logf("Namespace %s Pod %s Container %s - looking for one of the expected cgroup values %s in path %s", - pod.Namespace, pod.Name, cName, expectedCgValues, cgPath) - cgValue, _, err := ExecCommandInContainerWithFullOutput(f, pod.Name, cName, "/bin/sh", "-c", cmd) - if err != nil { - return fmt.Errorf("failed to find one of the expected cgroup values %q in container cgroup %q", expectedCgValues, cgPath) - } - cgValue = strings.Trim(cgValue, "\n") - - if err := framework.Gomega().Expect(cgValue).To(gomega.BeElementOf(expectedCgValues)); err != nil { - return fmt.Errorf("value of cgroup %q for container %q should match one of the expectations: %w", cgPath, cName, err) - } - - return nil -} - -// VerifyOomScoreAdjValue verifies that oom_score_adj for pid 1 (pidof init/systemd -> app) -// has the expected value in specified container of the pod. It execs into the container, -// reads the oom_score_adj value from procfs, and compares it against the expected value. -func VerifyOomScoreAdjValue(f *framework.Framework, pod *v1.Pod, cName, expectedOomScoreAdj string) error { - cmd := "cat /proc/1/oom_score_adj" - framework.Logf("Namespace %s Pod %s Container %s - looking for oom_score_adj value %s", - pod.Namespace, pod.Name, cName, expectedOomScoreAdj) - oomScoreAdj, _, err := ExecCommandInContainerWithFullOutput(f, pod.Name, cName, "/bin/sh", "-c", cmd) - if err != nil { - return fmt.Errorf("failed to find expected value %s for container app process", expectedOomScoreAdj) - } - oomScoreAdj = strings.Trim(oomScoreAdj, "\n") - if oomScoreAdj != expectedOomScoreAdj { - return fmt.Errorf("oom_score_adj value %s not equal to expected %s", oomScoreAdj, expectedOomScoreAdj) - } - return nil -} - -// IsPodOnCgroupv2Node checks whether the pod is running on cgroupv2 node. -// TODO: Deduplicate this function with NPD cluster e2e test: -// https://github.com/kubernetes/kubernetes/blob/2049360379bcc5d6467769cef112e6e492d3d2f0/test/e2e/node/node_problem_detector.go#L369 -func IsPodOnCgroupv2Node(f *framework.Framework, pod *v1.Pod) bool { - cmd := "mount -t cgroup2" - out, _, err := ExecCommandInContainerWithFullOutput(f, pod.Name, pod.Spec.Containers[0].Name, "/bin/sh", "-c", cmd) - if err != nil { - return false - } - return len(out) != 0 -} - -// TODO: Remove the rounded cpu limit values when https://github.com/opencontainers/runc/issues/4622 -// is fixed. -func GetCPULimitCgroupExpectations(cpuLimit *resource.Quantity) []string { - var expectedCPULimits []string - milliCPULimit := cpuLimit.MilliValue() - - cpuQuota := kubecm.MilliCPUToQuota(milliCPULimit, kubecm.QuotaPeriod) - if cpuLimit.IsZero() { - cpuQuota = -1 - } - expectedCPULimits = append(expectedCPULimits, getExpectedCPULimitFromCPUQuota(cpuQuota)) - - if milliCPULimit%10 != 0 && cpuQuota != -1 { - roundedCPULimit := (milliCPULimit/10 + 1) * 10 - cpuQuotaRounded := kubecm.MilliCPUToQuota(roundedCPULimit, kubecm.QuotaPeriod) - expectedCPULimits = append(expectedCPULimits, getExpectedCPULimitFromCPUQuota(cpuQuotaRounded)) - } - - return expectedCPULimits -} - -func getExpectedCPULimitFromCPUQuota(cpuQuota int64) string { - expectedCPULimitString := strconv.FormatInt(cpuQuota, 10) - if *podOnCgroupv2Node { - if expectedCPULimitString == "-1" { - expectedCPULimitString = "max" - } - expectedCPULimitString = fmt.Sprintf("%s %s", expectedCPULimitString, CPUPeriod) - } - return expectedCPULimitString -} diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/pv/wait.go b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/wait.go index ebfe227af..aa94b1708 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/pv/wait.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/pv/wait.go @@ -76,11 +76,16 @@ func WaitForPersistentVolumeClaimModificationFailure(ctx context.Context, c clie desiredClass := ptr.Deref(claim.Spec.VolumeAttributesClassName, "") var match = func(claim *v1.PersistentVolumeClaim) bool { + foundErrorCondition := false for _, condition := range claim.Status.Conditions { - if condition.Type != v1.PersistentVolumeClaimVolumeModifyVolumeError { - return false + if condition.Type == v1.PersistentVolumeClaimVolumeModifyVolumeError { + foundErrorCondition = true } } + // if no error found it must be an error + if !foundErrorCondition { + return false + } // check if claim's current volume attributes class is NOT desired one, and has appropriate ModifyVolumeStatus currentClass := ptr.Deref(claim.Status.CurrentVolumeAttributesClassName, "") diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go index abe4bfda1..bb7000800 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/test_context.go @@ -28,6 +28,7 @@ import ( "os" "path" "path/filepath" + "slices" "sort" "strings" "time" @@ -613,6 +614,19 @@ func AfterReadingAllFlags(t *TestContextType) { } ginkgo.ReportAfterSuite("Kubernetes e2e JUnit report", func(report ginkgo.Report) { + // Sort specs by full name. The default is by start (or completion?) time, + // which is less useful in spyglass because those times are not shown + // and thus tests seem to be listed with no apparent order. + slices.SortFunc(report.SpecReports, func(a, b types.SpecReport) int { + res := strings.Compare(a.FullText(), b.FullText()) + if res == 0 { + // Use start time as tie-breaker in the unlikely + // case that two specs have the same full name. + return a.StartTime.Compare(b.StartTime) + } + return res + }) + // With Ginkgo v1, we used to write one file per // parallel node. Now Ginkgo v2 automatically merges // all results into a report for us. The 01 suffix is diff --git a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go index 7eed8e367..ba6a7c77d 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/framework/util.go +++ b/vendor/k8s.io/kubernetes/test/e2e/framework/util.go @@ -413,6 +413,7 @@ func CheckTestingNSDeletedExcept(ctx context.Context, c clientset.Interface, ski // WaitForServiceEndpointsNum waits until there are EndpointSlices for serviceName // containing a total of expectNum endpoints. (If the service is dual-stack, expectNum // must count the endpoints of both IP families.) +// Deprecated: use e2eendpointslice.WaitForEndpointCount or other related functions. func WaitForServiceEndpointsNum(ctx context.Context, c clientset.Interface, namespace, serviceName string, expectNum int, interval, timeout time.Duration) error { return wait.PollUntilContextTimeout(ctx, interval, timeout, false, func(ctx context.Context) (bool, error) { Logf("Waiting for amount of service:%s endpoints to be %d", serviceName, expectNum) diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go index 94c843100..a0cdafe18 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/create.go @@ -29,7 +29,6 @@ import ( v1 "k8s.io/api/core/v1" rbacv1 "k8s.io/api/rbac/v1" storagev1 "k8s.io/api/storage/v1" - storagev1beta1 "k8s.io/api/storage/v1beta1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -316,7 +315,7 @@ func patchItemRecursively(f *framework.Framework, driverNamespace *v1.Namespace, PatchName(f, &item.Name) case *storagev1.StorageClass: PatchName(f, &item.Name) - case *storagev1beta1.VolumeAttributesClass: + case *storagev1.VolumeAttributesClass: PatchName(f, &item.Name) case *storagev1.CSIDriver: PatchName(f, &item.Name) @@ -625,16 +624,16 @@ func (*storageClassFactory) Create(ctx context.Context, f *framework.Framework, type volumeAttributesClassFactory struct{} func (f *volumeAttributesClassFactory) New() runtime.Object { - return &storagev1beta1.VolumeAttributesClass{} + return &storagev1.VolumeAttributesClass{} } func (*volumeAttributesClassFactory) Create(ctx context.Context, f *framework.Framework, ns *v1.Namespace, i interface{}) (func(ctx context.Context) error, error) { - item, ok := i.(*storagev1beta1.VolumeAttributesClass) + item, ok := i.(*storagev1.VolumeAttributesClass) if !ok { return nil, errorItemNotSupported } - client := f.ClientSet.StorageV1beta1().VolumeAttributesClasses() + client := f.ClientSet.StorageV1().VolumeAttributesClasses() if _, err := client.Create(ctx, item, metav1.CreateOptions{}); err != nil { return nil, fmt.Errorf("create VolumeAttributesClass: %w", err) } diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/file.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/file.go new file mode 100644 index 000000000..a6a913319 --- /dev/null +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/file.go @@ -0,0 +1,41 @@ +/* +Copyright 2025 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package utils + +import ( + "fmt" + "hash/crc32" +) + +// The max length for ntfs, ext4, xfs and btrfs. +const maxFileNameLength = 255 + +// Shorten a file name to size allowed by the most common filesystems. +// If the filename is too long, cut it + add a short hash (crc32) that makes it unique. +// Note that the input should be a single file / directory name, not a path +// composed of several directories. +func ShortenFileName(filename string) string { + if len(filename) <= maxFileNameLength { + return filename + } + + hash := crc32.ChecksumIEEE([]byte(filename)) + hashString := fmt.Sprintf("%x", hash) + hashLen := len(hashString) + + return fmt.Sprintf("%s-%s", filename[:maxFileNameLength-1-hashLen], hashString) +} diff --git a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go index 603f86e2c..a4d72721f 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go +++ b/vendor/k8s.io/kubernetes/test/e2e/storage/utils/pod.go @@ -22,8 +22,8 @@ import ( "io" "os" "path" + "path/filepath" "regexp" - "strings" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" @@ -68,6 +68,12 @@ func StartPodLogs(ctx context.Context, f *framework.Framework, driverNamespace * testName = append(testName, reg.ReplaceAllString(test.LeafNodeText, "_")) } } + + // Make sure each directory name is short enough for Linux + Windows + for i, testNameComponent := range testName { + testName[i] = ShortenFileName(testNameComponent) + } + // We end the prefix with a slash to ensure that all logs // end up in a directory named after the current test. // @@ -76,7 +82,7 @@ func StartPodLogs(ctx context.Context, f *framework.Framework, driverNamespace * // keeps each directory name smaller (the full test // name at one point exceeded 256 characters, which was // too much for some filesystems). - logDir := framework.TestContext.ReportDir + "/" + strings.Join(testName, "/") + logDir := filepath.Join(framework.TestContext.ReportDir, filepath.Join(testName...)) to.LogPathPrefix = logDir + "/" err := os.MkdirAll(logDir, 0755) diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/gpu/gce/nvidia-driver-installer.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/gpu/gce/nvidia-driver-installer.yaml index c23670087..24be2839b 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/gpu/gce/nvidia-driver-installer.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/gpu/gce/nvidia-driver-installer.yaml @@ -142,6 +142,6 @@ spec: - name: nvidia-config mountPath: /etc/nvidia containers: - - image: "registry.k8s.io/pause:3.10" + - image: "registry.k8s.io/pause:3.10.1" name: pause diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml index 60a1a6fab..11fe740b9 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: master - image: docker.io/library/redis:5.0.5-alpine + image: registry.k8s.io/e2e-test-images/redis:5.0.5-alpine resources: requests: cpu: 100m diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-slave-controller.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-slave-controller.yaml index 3376794b3..7f46fcbdd 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-slave-controller.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/guestbook/legacy/redis-slave-controller.yaml @@ -17,7 +17,7 @@ spec: spec: containers: - name: slave - image: docker.io/library/redis:5.0.5-alpine + image: registry.k8s.io/e2e-test-images/redis:5.0.5-alpine # We are only implementing the dns option of: # https://github.com/kubernetes/examples/blob/97c7ed0eb6555a4b667d2877f965d392e00abc45/guestbook/redis-slave/run.sh command: [ "redis-server", "--slaveof", "redis-master", "6379" ] diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml index 9b5466086..cd2916ea6 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/kubectl/agnhost-primary-pod.yaml @@ -8,7 +8,7 @@ metadata: spec: containers: - name: primary - image: registry.k8s.io/e2e-test-images/agnhost:2.32 + image: registry.k8s.io/e2e-test-images/agnhost:2.54 env: - name: PRIMARY value: "true" @@ -21,7 +21,7 @@ spec: - mountPath: /agnhost-primary-data name: data - name: sentinel - image: registry.k8s.io/e2e-test-images/agnhost:2.32 + image: registry.k8s.io/e2e-test-images/agnhost:2.54 env: - name: SENTINEL value: "true" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/service.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/service.yaml deleted file mode 100644 index 5499b375c..000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: nginx - labels: - app: nginx -spec: - ports: - - port: 80 - name: web - clusterIP: None - selector: - app: nginx \ No newline at end of file diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/statefulset.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/statefulset.yaml deleted file mode 100644 index abab8e89b..000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/nginx/statefulset.yaml +++ /dev/null @@ -1,34 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: web -spec: - serviceName: "nginx" - replicas: 3 - selector: - matchLabels: - app: nginx - template: - metadata: - labels: - app: nginx - spec: - containers: - - name: nginx - image: {{.NginxImageNew}} - ports: - - containerPort: 80 - name: web - volumeMounts: - - name: www - mountPath: /usr/share/nginx/html - volumeClaimTemplates: - - metadata: - name: www - annotations: - volume.beta.kubernetes.io/storage-class: nginx-sc - spec: - accessModes: [ "ReadWriteOnce" ] - resources: - requests: - storage: 1Gi diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/service.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/service.yaml deleted file mode 100644 index 528ef6dad..000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# A headless service to create DNS records -apiVersion: v1 -kind: Service -metadata: - name: redis - labels: - app: redis -spec: - ports: - - port: 6379 - name: peer - # *.redis.default.svc.cluster.local - clusterIP: None - selector: - app: redis - publishNotReadyAddresses: true diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml deleted file mode 100644 index 84e0a82bc..000000000 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/statefulset/redis/statefulset.yaml +++ /dev/null @@ -1,81 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: rd -spec: - serviceName: "redis" - replicas: 3 - selector: - matchLabels: - app: redis - template: - metadata: - labels: - app: redis - spec: - initContainers: - - name: install - image: registry.k8s.io/e2e-test-images/pets/redis-installer:1.5 - imagePullPolicy: Always - args: - - "--install-into=/opt" - - "--work-dir=/work-dir" - volumeMounts: - - name: opt - mountPath: "/opt" - - name: workdir - mountPath: "/work-dir" - - name: bootstrap - image: debian:jessie - command: - - "/work-dir/peer-finder" - args: - - -on-start="/work-dir/on-start.sh" - - "-service=redis" - env: - - name: POD_NAMESPACE - valueFrom: - fieldRef: - apiVersion: v1 - fieldPath: metadata.namespace - volumeMounts: - - name: opt - mountPath: "/opt" - - name: workdir - mountPath: "/work-dir" - containers: - - name: redis - image: debian:jessie - ports: - - containerPort: 6379 - name: peer - command: - - /opt/redis/redis-server - args: - - /opt/redis/redis.conf - readinessProbe: - exec: - command: - - sh - - -c - - "/opt/redis/redis-cli -h $(hostname) ping" - initialDelaySeconds: 15 - timeoutSeconds: 5 - volumeMounts: - - name: datadir - mountPath: /data - - name: opt - mountPath: /opt - volumes: - - name: opt - emptyDir: {} - - name: workdir - emptyDir: {} - volumeClaimTemplates: - - metadata: - name: datadir - spec: - accessModes: [ "ReadWriteOnce" ] - resources: - requests: - storage: 1Gi diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/any-volume-datasource/crd/populator.storage.k8s.io_volumepopulators.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/any-volume-datasource/crd/populator.storage.k8s.io_volumepopulators.yaml index 98cd376a1..488853fbf 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/any-volume-datasource/crd/populator.storage.k8s.io_volumepopulators.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/any-volume-datasource/crd/populator.storage.k8s.io_volumepopulators.yaml @@ -4,7 +4,6 @@ metadata: annotations: controller-gen.kubebuilder.io/version: v0.5.0 api-approved.kubernetes.io: https://github.com/kubernetes/enhancements/pull/2934 - creationTimestamp: null name: volumepopulators.populator.storage.k8s.io spec: group: populator.storage.k8s.io diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml index 666dd4e0f..35dc8c4b2 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/csi-hostpath-plugin.yaml @@ -354,7 +354,7 @@ spec: name: socket-dir - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.3.0 args: - -v=5 - --csi-address=/csi/csi.sock diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/run_group_snapshot_e2e.sh b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/run_group_snapshot_e2e.sh index 0ff1f9cb5..f62b40d84 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/run_group_snapshot_e2e.sh +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/external-snapshotter/volume-group-snapshots/run_group_snapshot_e2e.sh @@ -266,6 +266,8 @@ run_tests() { export KUBE_CONTAINER_RUNTIME=remote export KUBE_CONTAINER_RUNTIME_ENDPOINT=unix:///run/containerd/containerd.sock export KUBE_CONTAINER_RUNTIME_NAME=containerd + export SNAPSHOTTER_VERSION="${SNAPSHOTTER_VERSION:-v8.3.0}" + echo "SNAPSHOTTER_VERSION is $SNAPSHOTTER_VERSION" # ginkgo can take forever to exit, so we run it in the background and save the # PID, bash will not run traps while waiting on a process, but it will while # running a builtin like `wait`, saving the PID also allows us to forward the @@ -278,10 +280,10 @@ run_tests() { kubectl apply -f test/e2e/testing-manifests/storage-csi/external-snapshotter/groupsnapshot.storage.k8s.io_volumegroupsnapshotcontents.yaml || exit 1 kubectl apply -f test/e2e/testing-manifests/storage-csi/external-snapshotter/groupsnapshot.storage.k8s.io_volumegroupsnapshots.yaml || exit 1 - kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/v8.2.0/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml || exit 1 - curl -s https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/v8.2.0/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml | \ + kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/"${SNAPSHOTTER_VERSION}"/deploy/kubernetes/snapshot-controller/rbac-snapshot-controller.yaml || exit 1 + curl -s https://raw.githubusercontent.com/kubernetes-csi/external-snapshotter/refs/tags/"${SNAPSHOTTER_VERSION}"/deploy/kubernetes/snapshot-controller/setup-snapshot-controller.yaml | \ awk '/--leader-election=true/ {print; print " - \"--feature-gates=CSIVolumeGroupSnapshot=true\""; next}1' | \ -sed 's|image: registry.k8s.io/sig-storage/snapshot-controller:v8.0.1|image: registry.k8s.io/sig-storage/snapshot-controller:v8.2.0|' | \ +sed "s|image: registry.k8s.io/sig-storage/snapshot-controller:.*|image: registry.k8s.io/sig-storage/snapshot-controller:${SNAPSHOTTER_VERSION}|" | \ kubectl apply -f - || exit 1 diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml index 86d07389f..ed77430bf 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/gce-pd/controller_ss.yaml @@ -21,7 +21,7 @@ spec: serviceAccountName: csi-gce-pd-controller-sa containers: - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.3.0 args: - "--v=5" - "--csi-address=/csi/csi.sock" diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml index 3671e05c1..a5af9814a 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/hostpath/hostpath/csi-hostpath-plugin.yaml @@ -354,7 +354,7 @@ spec: name: socket-dir - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.3.0 args: - -v=5 - --csi-address=/csi/csi.sock diff --git a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml index 2be6611d3..cf5bbba29 100644 --- a/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml +++ b/vendor/k8s.io/kubernetes/test/e2e/testing-manifests/storage-csi/mock/csi-mock-driver-snapshotter.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: csi-mock containers: - name: csi-snapshotter - image: registry.k8s.io/sig-storage/csi-snapshotter:v8.2.0 + image: registry.k8s.io/sig-storage/csi-snapshotter:v8.3.0 args: - "--v=5" - "--csi-address=$(ADDRESS)" diff --git a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go index 606859306..157edb2af 100644 --- a/vendor/k8s.io/kubernetes/test/utils/image/manifest.go +++ b/vendor/k8s.io/kubernetes/test/utils/image/manifest.go @@ -28,7 +28,7 @@ import ( "regexp" "strings" - yaml "sigs.k8s.io/yaml/goyaml.v2" + yaml "go.yaml.in/yaml/v2" ) // RegistryList holds public and private image registries @@ -208,8 +208,6 @@ const ( Pause // Perl image Perl - // Redis image - Redis // RegressionIssue74839 image RegressionIssue74839 // ResourceConsumer image @@ -222,14 +220,14 @@ const ( func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config) { configs := map[ImageID]Config{} - configs[Agnhost] = Config{list.PromoterE2eRegistry, "agnhost", "2.53"} + configs[Agnhost] = Config{list.PromoterE2eRegistry, "agnhost", "2.56"} configs[AgnhostPrivate] = Config{list.PrivateRegistry, "agnhost", "2.6"} configs[AuthenticatedAlpine] = Config{list.GcAuthenticatedRegistry, "alpine", "3.7"} configs[APIServer] = Config{list.PromoterE2eRegistry, "sample-apiserver", "1.29.2"} configs[AppArmorLoader] = Config{list.PromoterE2eRegistry, "apparmor-loader", "1.4"} - configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.36.1-1"} + configs[BusyBox] = Config{list.PromoterE2eRegistry, "busybox", "1.37.0-1"} configs[DistrolessIptables] = Config{list.BuildImageRegistry, "distroless-iptables", "v0.7.13"} - configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.5.21-0"} + configs[Etcd] = Config{list.GcEtcdRegistry, "etcd", "3.6.4-0"} configs[Httpd] = Config{list.PromoterE2eRegistry, "httpd", "2.4.38-4"} configs[HttpdNew] = Config{list.PromoterE2eRegistry, "httpd", "2.4.39-4"} configs[InvalidRegistryImage] = Config{list.InvalidRegistry, "alpine", "3.1"} @@ -246,9 +244,8 @@ func initImageConfigs(list RegistryList) (map[ImageID]Config, map[ImageID]Config configs[Nonewprivs] = Config{list.PromoterE2eRegistry, "nonewprivs", "1.3"} configs[NonRoot] = Config{list.PromoterE2eRegistry, "nonroot", "1.4"} // Pause - when these values are updated, also update cmd/kubelet/app/options/container_runtime.go - configs[Pause] = Config{list.GcRegistry, "pause", "3.10"} + configs[Pause] = Config{list.GcRegistry, "pause", "3.10.1"} configs[Perl] = Config{list.PromoterE2eRegistry, "perl", "5.26"} - configs[Redis] = Config{list.PromoterE2eRegistry, "redis", "5.0.5-3"} configs[RegressionIssue74839] = Config{list.PromoterE2eRegistry, "regression-issue-74839", "1.2"} configs[ResourceConsumer] = Config{list.PromoterE2eRegistry, "resource-consumer", "1.13"} configs[VolumeNFSServer] = Config{list.PromoterE2eRegistry, "volume/nfs", "1.4"} diff --git a/vendor/k8s.io/kubernetes/test/utils/runners.go b/vendor/k8s.io/kubernetes/test/utils/runners.go index 29a66bf2f..c8b8bc947 100644 --- a/vendor/k8s.io/kubernetes/test/utils/runners.go +++ b/vendor/k8s.io/kubernetes/test/utils/runners.go @@ -44,7 +44,7 @@ import ( scaleclient "k8s.io/client-go/scale" "k8s.io/client-go/util/workqueue" imageutils "k8s.io/kubernetes/test/utils/image" - "k8s.io/utils/pointer" + "k8s.io/utils/ptr" "k8s.io/klog/v2" ) @@ -119,11 +119,12 @@ type RCConfig struct { Timeout time.Duration PodStatusFile *os.File Replicas int - CpuRequest int64 // millicores - CpuLimit int64 // millicores - MemRequest int64 // bytes - MemLimit int64 // bytes - GpuLimit int64 // count + CPURequest int64 // millicores + CPULimit int64 // millicores + MemRequest int64 // bytes + MemLimit int64 // bytes + GpuLimit int64 // count + PodResources *v1.ResourceRequirements // Pod-level resources ReadinessProbe *v1.Probe DNSPolicy *v1.DNSPolicy PriorityClassName string @@ -302,7 +303,7 @@ func (config *DeploymentConfig) create() error { Name: config.Name, }, Spec: apps.DeploymentSpec{ - Replicas: pointer.Int32(int32(config.Replicas)), + Replicas: ptr.To[int32](int32(config.Replicas)), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "name": config.Name, @@ -331,6 +332,10 @@ func (config *DeploymentConfig) create() error { }, } + if config.PodResources != nil { + deployment.Spec.Template.Spec.Resources = config.PodResources.DeepCopy() + } + if len(config.AdditionalContainers) > 0 { deployment.Spec.Template.Spec.Containers = append(deployment.Spec.Template.Spec.Containers, config.AdditionalContainers...) } @@ -373,7 +378,7 @@ func (config *ReplicaSetConfig) create() error { Name: config.Name, }, Spec: apps.ReplicaSetSpec{ - Replicas: pointer.Int32(int32(config.Replicas)), + Replicas: ptr.To[int32](int32(config.Replicas)), Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ "name": config.Name, @@ -402,6 +407,10 @@ func (config *ReplicaSetConfig) create() error { }, } + if config.PodResources != nil { + rs.Spec.Template.Spec.Resources = config.PodResources.DeepCopy() + } + if len(config.AdditionalContainers) > 0 { rs.Spec.Template.Spec.Containers = append(rs.Spec.Template.Spec.Containers, config.AdditionalContainers...) } @@ -445,7 +454,7 @@ func (config *RCConfig) create() error { Name: config.Name, }, Spec: v1.ReplicationControllerSpec{ - Replicas: pointer.Int32(int32(config.Replicas)), + Replicas: ptr.To[int32](int32(config.Replicas)), Selector: map[string]string{ "name": config.Name, }, @@ -478,6 +487,10 @@ func (config *RCConfig) create() error { }, } + if config.PodResources != nil { + rc.Spec.Template.Spec.Resources = config.PodResources.DeepCopy() + } + if len(config.AdditionalContainers) > 0 { rc.Spec.Template.Spec.Containers = append(rc.Spec.Template.Spec.Containers, config.AdditionalContainers...) } @@ -521,20 +534,20 @@ func (config *RCConfig) applyTo(template *v1.PodTemplateSpec) { c := &template.Spec.Containers[0] c.Ports = append(c.Ports, v1.ContainerPort{Name: k, ContainerPort: int32(v), HostPort: int32(v)}) } - if config.CpuLimit > 0 || config.MemLimit > 0 || config.GpuLimit > 0 { + if config.CPULimit > 0 || config.MemLimit > 0 || config.GpuLimit > 0 { template.Spec.Containers[0].Resources.Limits = v1.ResourceList{} } - if config.CpuLimit > 0 { - template.Spec.Containers[0].Resources.Limits[v1.ResourceCPU] = *resource.NewMilliQuantity(config.CpuLimit, resource.DecimalSI) + if config.CPULimit > 0 { + template.Spec.Containers[0].Resources.Limits[v1.ResourceCPU] = *resource.NewMilliQuantity(config.CPULimit, resource.DecimalSI) } if config.MemLimit > 0 { template.Spec.Containers[0].Resources.Limits[v1.ResourceMemory] = *resource.NewQuantity(config.MemLimit, resource.DecimalSI) } - if config.CpuRequest > 0 || config.MemRequest > 0 { + if config.CPURequest > 0 || config.MemRequest > 0 { template.Spec.Containers[0].Resources.Requests = v1.ResourceList{} } - if config.CpuRequest > 0 { - template.Spec.Containers[0].Resources.Requests[v1.ResourceCPU] = *resource.NewMilliQuantity(config.CpuRequest, resource.DecimalSI) + if config.CPURequest > 0 { + template.Spec.Containers[0].Resources.Requests[v1.ResourceCPU] = *resource.NewMilliQuantity(config.CPURequest, resource.DecimalSI) } if config.MemRequest > 0 { template.Spec.Containers[0].Resources.Requests[v1.ResourceMemory] = *resource.NewQuantity(config.MemRequest, resource.DecimalSI) diff --git a/vendor/k8s.io/kubernetes/third_party/forked/golang/LICENSE b/vendor/k8s.io/kubernetes/third_party/forked/golang/LICENSE deleted file mode 100644 index 6a66aea5e..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/golang/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/k8s.io/kubernetes/third_party/forked/golang/PATENTS b/vendor/k8s.io/kubernetes/third_party/forked/golang/PATENTS deleted file mode 100644 index 733099041..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/golang/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/k8s.io/kubernetes/third_party/forked/golang/expansion/expand.go b/vendor/k8s.io/kubernetes/third_party/forked/golang/expansion/expand.go deleted file mode 100644 index 6bf0ea8ce..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/golang/expansion/expand.go +++ /dev/null @@ -1,102 +0,0 @@ -package expansion - -import ( - "bytes" -) - -const ( - operator = '$' - referenceOpener = '(' - referenceCloser = ')' -) - -// syntaxWrap returns the input string wrapped by the expansion syntax. -func syntaxWrap(input string) string { - return string(operator) + string(referenceOpener) + input + string(referenceCloser) -} - -// MappingFuncFor returns a mapping function for use with Expand that -// implements the expansion semantics defined in the expansion spec; it -// returns the input string wrapped in the expansion syntax if no mapping -// for the input is found. -func MappingFuncFor(context ...map[string]string) func(string) string { - return func(input string) string { - for _, vars := range context { - val, ok := vars[input] - if ok { - return val - } - } - - return syntaxWrap(input) - } -} - -// Expand replaces variable references in the input string according to -// the expansion spec using the given mapping function to resolve the -// values of variables. -func Expand(input string, mapping func(string) string) string { - var buf bytes.Buffer - checkpoint := 0 - for cursor := 0; cursor < len(input); cursor++ { - if input[cursor] == operator && cursor+1 < len(input) { - // Copy the portion of the input string since the last - // checkpoint into the buffer - buf.WriteString(input[checkpoint:cursor]) - - // Attempt to read the variable name as defined by the - // syntax from the input string - read, isVar, advance := tryReadVariableName(input[cursor+1:]) - - if isVar { - // We were able to read a variable name correctly; - // apply the mapping to the variable name and copy the - // bytes into the buffer - buf.WriteString(mapping(read)) - } else { - // Not a variable name; copy the read bytes into the buffer - buf.WriteString(read) - } - - // Advance the cursor in the input string to account for - // bytes consumed to read the variable name expression - cursor += advance - - // Advance the checkpoint in the input string - checkpoint = cursor + 1 - } - } - - // Return the buffer and any remaining unwritten bytes in the - // input string. - return buf.String() + input[checkpoint:] -} - -// tryReadVariableName attempts to read a variable name from the input -// string and returns the content read from the input, whether that content -// represents a variable name to perform mapping on, and the number of bytes -// consumed in the input string. -// -// The input string is assumed not to contain the initial operator. -func tryReadVariableName(input string) (string, bool, int) { - switch input[0] { - case operator: - // Escaped operator; return it. - return input[0:1], false, 1 - case referenceOpener: - // Scan to expression closer - for i := 1; i < len(input); i++ { - if input[i] == referenceCloser { - return input[1:i], true, i + 1 - } - } - - // Incomplete reference; return it. - return string(operator) + string(referenceOpener), false, 1 - default: - // Not the beginning of an expression, ie, an operator - // that doesn't begin an expression. Return the operator - // and the first rune in the string. - return (string(operator) + string(input[0])), false, 1 - } -} diff --git a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/LICENSE b/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/LICENSE deleted file mode 100644 index 27448585a..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/LICENSE +++ /dev/null @@ -1,191 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - Copyright 2014 Docker, Inc. - - 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. diff --git a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/NOTICE b/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/NOTICE deleted file mode 100644 index 5c97abce4..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/NOTICE +++ /dev/null @@ -1,17 +0,0 @@ -runc - -Copyright 2012-2015 Docker, Inc. - -This product includes software developed at Docker, Inc. (http://www.docker.com). - -The following is courtesy of our legal counsel: - - -Use and transfer of Docker may be subject to certain restrictions by the -United States and other governments. -It is your responsibility to ensure that your use and/or transfer does not -violate applicable laws. - -For more information, please see http://www.bis.doc.gov - -See also http://www.apache.org/dev/crypto.html and/or seek legal counsel. diff --git a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_linux.go b/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_linux.go deleted file mode 100644 index f83cbb225..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_linux.go +++ /dev/null @@ -1,22 +0,0 @@ -package apparmor - -import ( - "os" - "sync" -) - -var ( - appArmorEnabled bool - checkAppArmor sync.Once -) - -// IsEnabled returns true if apparmor is enabled for the host. -func IsEnabled() bool { - checkAppArmor.Do(func() { - if _, err := os.Stat("/sys/kernel/security/apparmor"); err == nil { - buf, err := os.ReadFile("/sys/module/apparmor/parameters/enabled") - appArmorEnabled = err == nil && len(buf) > 1 && buf[0] == 'Y' - } - }) - return appArmorEnabled -} diff --git a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go b/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go deleted file mode 100644 index 28be1d2e8..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/apparmor/apparmor_unsupported.go +++ /dev/null @@ -1,8 +0,0 @@ -//go:build !linux -// +build !linux - -package apparmor - -func IsEnabled() bool { - return false -} diff --git a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/utils/utils.go b/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/utils/utils.go deleted file mode 100644 index 76a093330..000000000 --- a/vendor/k8s.io/kubernetes/third_party/forked/libcontainer/utils/utils.go +++ /dev/null @@ -1,35 +0,0 @@ -package utils - -import ( - "os" - "path/filepath" -) - -// CleanPath makes a path safe for use with filepath.Join. This is done by not -// only cleaning the path, but also (if the path is relative) adding a leading -// '/' and cleaning it (then removing the leading '/'). This ensures that a -// path resulting from prepending another path will always resolve to lexically -// be a subdirectory of the prefixed path. This is all done lexically, so paths -// that include symlinks won't be safe as a result of using CleanPath. -func CleanPath(path string) string { - // Deal with empty strings nicely. - if path == "" { - return "" - } - - // Ensure that all paths are cleaned (especially problematic ones like - // "/../../../../../" which can cause lots of issues). - path = filepath.Clean(path) - - // If the path isn't absolute, we need to do more processing to fix paths - // such as "../../../..//some/path". We also shouldn't convert absolute - // paths to relative ones. - if !filepath.IsAbs(path) { - path = filepath.Clean(string(os.PathSeparator) + path) - // This can't fail, as (by definition) all paths are relative to root. - path, _ = filepath.Rel(string(os.PathSeparator), path) - } - - // Clean the path again for good measure. - return filepath.Clean(path) -} diff --git a/vendor/k8s.io/utils/cpuset/OWNERS b/vendor/k8s.io/utils/cpuset/OWNERS deleted file mode 100644 index 0ec2b0852..000000000 --- a/vendor/k8s.io/utils/cpuset/OWNERS +++ /dev/null @@ -1,8 +0,0 @@ -# See the OWNERS docs at https://go.k8s.io/owners - -approvers: - - dchen1107 - - derekwaynecarr - - ffromani - - klueska - - SergeyKanzhelev diff --git a/vendor/k8s.io/utils/cpuset/cpuset.go b/vendor/k8s.io/utils/cpuset/cpuset.go deleted file mode 100644 index 52912d95b..000000000 --- a/vendor/k8s.io/utils/cpuset/cpuset.go +++ /dev/null @@ -1,256 +0,0 @@ -/* -Copyright 2017 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -// Package cpuset represents a collection of CPUs in a 'set' data structure. -// -// It can be used to represent core IDs, hyper thread siblings, CPU nodes, or processor IDs. -// -// The only special thing about this package is that -// methods are provided to convert back and forth from Linux 'list' syntax. -// See http://man7.org/linux/man-pages/man7/cpuset.7.html#FORMATS for details. -// -// Future work can migrate this to use a 'set' library, and relax the dubious 'immutable' property. -// -// This package was originally developed in the 'kubernetes' repository. -package cpuset - -import ( - "bytes" - "fmt" - "reflect" - "sort" - "strconv" - "strings" -) - -// CPUSet is a thread-safe, immutable set-like data structure for CPU IDs. -type CPUSet struct { - elems map[int]struct{} -} - -// New returns a new CPUSet containing the supplied elements. -func New(cpus ...int) CPUSet { - s := CPUSet{ - elems: map[int]struct{}{}, - } - for _, c := range cpus { - s.add(c) - } - return s -} - -// add adds the supplied elements to the CPUSet. -// It is intended for internal use only, since it mutates the CPUSet. -func (s CPUSet) add(elems ...int) { - for _, elem := range elems { - s.elems[elem] = struct{}{} - } -} - -// Size returns the number of elements in this set. -func (s CPUSet) Size() int { - return len(s.elems) -} - -// IsEmpty returns true if there are zero elements in this set. -func (s CPUSet) IsEmpty() bool { - return s.Size() == 0 -} - -// Contains returns true if the supplied element is present in this set. -func (s CPUSet) Contains(cpu int) bool { - _, found := s.elems[cpu] - return found -} - -// Equals returns true if the supplied set contains exactly the same elements -// as this set (s IsSubsetOf s2 and s2 IsSubsetOf s). -func (s CPUSet) Equals(s2 CPUSet) bool { - return reflect.DeepEqual(s.elems, s2.elems) -} - -// filter returns a new CPU set that contains all of the elements from this -// set that match the supplied predicate, without mutating the source set. -func (s CPUSet) filter(predicate func(int) bool) CPUSet { - r := New() - for cpu := range s.elems { - if predicate(cpu) { - r.add(cpu) - } - } - return r -} - -// IsSubsetOf returns true if the supplied set contains all the elements -func (s CPUSet) IsSubsetOf(s2 CPUSet) bool { - result := true - for cpu := range s.elems { - if !s2.Contains(cpu) { - result = false - break - } - } - return result -} - -// Union returns a new CPU set that contains all of the elements from this -// set and all of the elements from the supplied sets, without mutating -// either source set. -func (s CPUSet) Union(s2 ...CPUSet) CPUSet { - r := New() - for cpu := range s.elems { - r.add(cpu) - } - for _, cs := range s2 { - for cpu := range cs.elems { - r.add(cpu) - } - } - return r -} - -// Intersection returns a new CPU set that contains all of the elements -// that are present in both this set and the supplied set, without mutating -// either source set. -func (s CPUSet) Intersection(s2 CPUSet) CPUSet { - return s.filter(func(cpu int) bool { return s2.Contains(cpu) }) -} - -// Difference returns a new CPU set that contains all of the elements that -// are present in this set and not the supplied set, without mutating either -// source set. -func (s CPUSet) Difference(s2 CPUSet) CPUSet { - return s.filter(func(cpu int) bool { return !s2.Contains(cpu) }) -} - -// List returns a slice of integers that contains all elements from -// this set. The list is sorted. -func (s CPUSet) List() []int { - result := s.UnsortedList() - sort.Ints(result) - return result -} - -// UnsortedList returns a slice of integers that contains all elements from -// this set. -func (s CPUSet) UnsortedList() []int { - result := make([]int, 0, len(s.elems)) - for cpu := range s.elems { - result = append(result, cpu) - } - return result -} - -// String returns a new string representation of the elements in this CPU set -// in canonical linux CPU list format. -// -// See: http://man7.org/linux/man-pages/man7/cpuset.7.html#FORMATS -func (s CPUSet) String() string { - if s.IsEmpty() { - return "" - } - - elems := s.List() - - type rng struct { - start int - end int - } - - ranges := []rng{{elems[0], elems[0]}} - - for i := 1; i < len(elems); i++ { - lastRange := &ranges[len(ranges)-1] - // if this element is adjacent to the high end of the last range - if elems[i] == lastRange.end+1 { - // then extend the last range to include this element - lastRange.end = elems[i] - continue - } - // otherwise, start a new range beginning with this element - ranges = append(ranges, rng{elems[i], elems[i]}) - } - - // construct string from ranges - var result bytes.Buffer - for _, r := range ranges { - if r.start == r.end { - result.WriteString(strconv.Itoa(r.start)) - } else { - result.WriteString(fmt.Sprintf("%d-%d", r.start, r.end)) - } - result.WriteString(",") - } - return strings.TrimRight(result.String(), ",") -} - -// Parse CPUSet constructs a new CPU set from a Linux CPU list formatted string. -// -// See: http://man7.org/linux/man-pages/man7/cpuset.7.html#FORMATS -func Parse(s string) (CPUSet, error) { - // Handle empty string. - if s == "" { - return New(), nil - } - - result := New() - - // Split CPU list string: - // "0-5,34,46-48" => ["0-5", "34", "46-48"] - ranges := strings.Split(s, ",") - - for _, r := range ranges { - boundaries := strings.SplitN(r, "-", 2) - if len(boundaries) == 1 { - // Handle ranges that consist of only one element like "34". - elem, err := strconv.Atoi(boundaries[0]) - if err != nil { - return New(), err - } - result.add(elem) - } else if len(boundaries) == 2 { - // Handle multi-element ranges like "0-5". - start, err := strconv.Atoi(boundaries[0]) - if err != nil { - return New(), err - } - end, err := strconv.Atoi(boundaries[1]) - if err != nil { - return New(), err - } - if start > end { - return New(), fmt.Errorf("invalid range %q (%d > %d)", r, start, end) - } - // start == end is acceptable (1-1 -> 1) - - // Add all elements to the result. - // e.g. "0-5", "46-48" => [0, 1, 2, 3, 4, 5, 46, 47, 48]. - for e := start; e <= end; e++ { - result.add(e) - } - } - } - return result, nil -} - -// Clone returns a copy of this CPU set. -func (s CPUSet) Clone() CPUSet { - r := New() - for elem := range s.elems { - r.add(elem) - } - return r -} diff --git a/vendor/k8s.io/utils/inotify/LICENSE b/vendor/k8s.io/utils/inotify/LICENSE deleted file mode 100644 index 6a66aea5e..000000000 --- a/vendor/k8s.io/utils/inotify/LICENSE +++ /dev/null @@ -1,27 +0,0 @@ -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/vendor/k8s.io/utils/inotify/PATENTS b/vendor/k8s.io/utils/inotify/PATENTS deleted file mode 100644 index 733099041..000000000 --- a/vendor/k8s.io/utils/inotify/PATENTS +++ /dev/null @@ -1,22 +0,0 @@ -Additional IP Rights Grant (Patents) - -"This implementation" means the copyrightable works distributed by -Google as part of the Go project. - -Google hereby grants to You a perpetual, worldwide, non-exclusive, -no-charge, royalty-free, irrevocable (except as stated in this section) -patent license to make, have made, use, offer to sell, sell, import, -transfer and otherwise run, modify and propagate the contents of this -implementation of Go, where such license applies only to those patent -claims, both currently owned or controlled by Google and acquired in -the future, licensable by Google that are necessarily infringed by this -implementation of Go. This grant does not include claims that would be -infringed only as a consequence of further modification of this -implementation. If you or your agent or exclusive licensee institute or -order or agree to the institution of patent litigation against any -entity (including a cross-claim or counterclaim in a lawsuit) alleging -that this implementation of Go or any code incorporated within this -implementation of Go constitutes direct or contributory patent -infringement, or inducement of patent infringement, then any patent -rights granted to you under this License for this implementation of Go -shall terminate as of the date such litigation is filed. diff --git a/vendor/k8s.io/utils/inotify/README.md b/vendor/k8s.io/utils/inotify/README.md deleted file mode 100644 index fbaa1667a..000000000 --- a/vendor/k8s.io/utils/inotify/README.md +++ /dev/null @@ -1,5 +0,0 @@ -This is a fork of golang.org/x/exp/inotify before it was deleted. - -Please use gopkg.in/fsnotify.v1 instead. - -For updates, see: https://github.com/fsnotify/fsnotify diff --git a/vendor/k8s.io/utils/inotify/inotify.go b/vendor/k8s.io/utils/inotify/inotify.go deleted file mode 100644 index 6e9970424..000000000 --- a/vendor/k8s.io/utils/inotify/inotify.go +++ /dev/null @@ -1,45 +0,0 @@ -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package inotify // import "k8s.io/utils/inotify" - -import ( - "sync" -) - -// Event represents a notification -type Event struct { - Mask uint32 // Mask of events - Cookie uint32 // Unique cookie associating related events (for rename(2)) - Name string // File name (optional) -} - -type watch struct { - wd uint32 // Watch descriptor (as returned by the inotify_add_watch() syscall) - flags uint32 // inotify flags of this watch (see inotify(7) for the list of valid flags) -} - -// Watcher represents an inotify instance -type Watcher struct { - mu sync.Mutex - fd int // File descriptor (as returned by the inotify_init() syscall) - watches map[string]*watch // Map of inotify watches (key: path) - paths map[int]string // Map of watched paths (key: watch descriptor) - Error chan error // Errors are sent on this channel - Event chan *Event // Events are returned on this channel - done chan bool // Channel for sending a "quit message" to the reader goroutine - isClosed bool // Set to true when Close() is first called -} diff --git a/vendor/k8s.io/utils/inotify/inotify_linux.go b/vendor/k8s.io/utils/inotify/inotify_linux.go deleted file mode 100644 index 2b9eabbdc..000000000 --- a/vendor/k8s.io/utils/inotify/inotify_linux.go +++ /dev/null @@ -1,315 +0,0 @@ -//go:build linux -// +build linux - -// Copyright 2010 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 inotify implements a wrapper for the Linux inotify system. - -Example: - - watcher, err := inotify.NewWatcher() - if err != nil { - log.Fatal(err) - } - err = watcher.Watch("/tmp") - if err != nil { - log.Fatal(err) - } - for { - select { - case ev := <-watcher.Event: - log.Println("event:", ev) - case err := <-watcher.Error: - log.Println("error:", err) - } - } -*/ -package inotify // import "k8s.io/utils/inotify" - -import ( - "errors" - "fmt" - "os" - "strings" - "syscall" - "unsafe" -) - -// NewWatcher creates and returns a new inotify instance using inotify_init(2) -func NewWatcher() (*Watcher, error) { - fd, errno := syscall.InotifyInit1(syscall.IN_CLOEXEC) - if fd == -1 { - return nil, os.NewSyscallError("inotify_init", errno) - } - w := &Watcher{ - fd: fd, - watches: make(map[string]*watch), - paths: make(map[int]string), - Event: make(chan *Event), - Error: make(chan error), - done: make(chan bool, 1), - } - - go w.readEvents() - return w, nil -} - -// Close closes an inotify watcher instance -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the inotify instance -func (w *Watcher) Close() error { - if w.isClosed { - return nil - } - w.isClosed = true - - // Send "quit" message to the reader goroutine - w.done <- true - for path := range w.watches { - w.RemoveWatch(path) - } - - return nil -} - -// AddWatch adds path to the watched file set. -// The flags are interpreted as described in inotify_add_watch(2). -func (w *Watcher) AddWatch(path string, flags uint32) error { - if w.isClosed { - return errors.New("inotify instance already closed") - } - - watchEntry, found := w.watches[path] - if found { - watchEntry.flags |= flags - flags |= syscall.IN_MASK_ADD - } - - w.mu.Lock() // synchronize with readEvents goroutine - - wd, err := syscall.InotifyAddWatch(w.fd, path, flags) - if err != nil { - w.mu.Unlock() - return &os.PathError{ - Op: "inotify_add_watch", - Path: path, - Err: err, - } - } - - if !found { - w.watches[path] = &watch{wd: uint32(wd), flags: flags} - w.paths[wd] = path - } - w.mu.Unlock() - return nil -} - -// Watch adds path to the watched file set, watching all events. -func (w *Watcher) Watch(path string) error { - return w.AddWatch(path, InAllEvents) -} - -// RemoveWatch removes path from the watched file set. -func (w *Watcher) RemoveWatch(path string) error { - watch, ok := w.watches[path] - if !ok { - return fmt.Errorf("can't remove non-existent inotify watch for: %s", path) - } - success, errno := syscall.InotifyRmWatch(w.fd, watch.wd) - if success == -1 { - // when file descriptor or watch descriptor not found, InotifyRmWatch syscall return EINVAL error - // if return error, it may lead this path remain in watches and paths map, and no other event can trigger remove action. - if errno != syscall.EINVAL { - return os.NewSyscallError("inotify_rm_watch", errno) - } - } - delete(w.watches, path) - // Locking here to protect the read from paths in readEvents. - w.mu.Lock() - delete(w.paths, int(watch.wd)) - w.mu.Unlock() - return nil -} - -// readEvents reads from the inotify file descriptor, converts the -// received events into Event objects and sends them via the Event channel -func (w *Watcher) readEvents() { - var buf [syscall.SizeofInotifyEvent * 4096]byte - - for { - n, err := syscall.Read(w.fd, buf[:]) - // See if there is a message on the "done" channel - var done bool - select { - case done = <-w.done: - default: - } - - // If EOF or a "done" message is received - if n == 0 || done { - // The syscall.Close can be slow. Close - // w.Event first. - close(w.Event) - err := syscall.Close(w.fd) - if err != nil { - w.Error <- os.NewSyscallError("close", err) - } - close(w.Error) - return - } - if n < 0 { - w.Error <- os.NewSyscallError("read", err) - continue - } - if n < syscall.SizeofInotifyEvent { - w.Error <- errors.New("inotify: short read in readEvents()") - continue - } - - var offset uint32 - // We don't know how many events we just read into the buffer - // While the offset points to at least one whole event... - for offset <= uint32(n-syscall.SizeofInotifyEvent) { - // Point "raw" to the event in the buffer - raw := (*syscall.InotifyEvent)(unsafe.Pointer(&buf[offset])) - event := new(Event) - event.Mask = uint32(raw.Mask) - event.Cookie = uint32(raw.Cookie) - nameLen := uint32(raw.Len) - // If the event happened to the watched directory or the watched file, the kernel - // doesn't append the filename to the event, but we would like to always fill the - // the "Name" field with a valid filename. We retrieve the path of the watch from - // the "paths" map. - w.mu.Lock() - name, ok := w.paths[int(raw.Wd)] - w.mu.Unlock() - if ok { - event.Name = name - if nameLen > 0 { - // Point "bytes" at the first byte of the filename - bytes := (*[syscall.PathMax]byte)(unsafe.Pointer(&buf[offset+syscall.SizeofInotifyEvent])) - // The filename is padded with NUL bytes. TrimRight() gets rid of those. - event.Name += "/" + strings.TrimRight(string(bytes[0:nameLen]), "\000") - } - // Send the event on the events channel - w.Event <- event - } - // Move to the next event in the buffer - offset += syscall.SizeofInotifyEvent + nameLen - } - } -} - -// String formats the event e in the form -// "filename: 0xEventMask = IN_ACCESS|IN_ATTRIB_|..." -func (e *Event) String() string { - var events string - - m := e.Mask - for _, b := range eventBits { - if m&b.Value == b.Value { - m &^= b.Value - events += "|" + b.Name - } - } - - if m != 0 { - events += fmt.Sprintf("|%#x", m) - } - if len(events) > 0 { - events = " == " + events[1:] - } - - return fmt.Sprintf("%q: %#x%s", e.Name, e.Mask, events) -} - -const ( - // Options for inotify_init() are not exported - // IN_CLOEXEC uint32 = syscall.IN_CLOEXEC - // IN_NONBLOCK uint32 = syscall.IN_NONBLOCK - - // Options for AddWatch - - // InDontFollow : Don't dereference pathname if it is a symbolic link - InDontFollow uint32 = syscall.IN_DONT_FOLLOW - // InOneshot : Monitor the filesystem object corresponding to pathname for one event, then remove from watch list - InOneshot uint32 = syscall.IN_ONESHOT - // InOnlydir : Watch pathname only if it is a directory - InOnlydir uint32 = syscall.IN_ONLYDIR - - // The "IN_MASK_ADD" option is not exported, as AddWatch - // adds it automatically, if there is already a watch for the given path - // IN_MASK_ADD uint32 = syscall.IN_MASK_ADD - - // Events - - // InAccess : File was accessed - InAccess uint32 = syscall.IN_ACCESS - // InAllEvents : Bit mask for all notify events - InAllEvents uint32 = syscall.IN_ALL_EVENTS - // InAttrib : Metadata changed - InAttrib uint32 = syscall.IN_ATTRIB - // InClose : Equates to IN_CLOSE_WRITE | IN_CLOSE_NOWRITE - InClose uint32 = syscall.IN_CLOSE - // InCloseNowrite : File or directory not opened for writing was closed - InCloseNowrite uint32 = syscall.IN_CLOSE_NOWRITE - // InCloseWrite : File opened for writing was closed - InCloseWrite uint32 = syscall.IN_CLOSE_WRITE - // InCreate : File/directory created in watched directory - InCreate uint32 = syscall.IN_CREATE - // InDelete : File/directory deleted from watched directory - InDelete uint32 = syscall.IN_DELETE - // InDeleteSelf : Watched file/directory was itself deleted - InDeleteSelf uint32 = syscall.IN_DELETE_SELF - // InModify : File was modified - InModify uint32 = syscall.IN_MODIFY - // InMove : Equates to IN_MOVED_FROM | IN_MOVED_TO - InMove uint32 = syscall.IN_MOVE - // InMovedFrom : Generated for the directory containing the old filename when a file is renamed - InMovedFrom uint32 = syscall.IN_MOVED_FROM - // InMovedTo : Generated for the directory containing the new filename when a file is renamed - InMovedTo uint32 = syscall.IN_MOVED_TO - // InMoveSelf : Watched file/directory was itself moved - InMoveSelf uint32 = syscall.IN_MOVE_SELF - // InOpen : File or directory was opened - InOpen uint32 = syscall.IN_OPEN - - // Special events - - // InIsdir : Subject of this event is a directory - InIsdir uint32 = syscall.IN_ISDIR - // InIgnored : Watch was removed explicitly or automatically - InIgnored uint32 = syscall.IN_IGNORED - // InQOverflow : Event queue overflowed - InQOverflow uint32 = syscall.IN_Q_OVERFLOW - // InUnmount : Filesystem containing watched object was unmounted - InUnmount uint32 = syscall.IN_UNMOUNT -) - -var eventBits = []struct { - Value uint32 - Name string -}{ - {InAccess, "IN_ACCESS"}, - {InAttrib, "IN_ATTRIB"}, - {InClose, "IN_CLOSE"}, - {InCloseNowrite, "IN_CLOSE_NOWRITE"}, - {InCloseWrite, "IN_CLOSE_WRITE"}, - {InCreate, "IN_CREATE"}, - {InDelete, "IN_DELETE"}, - {InDeleteSelf, "IN_DELETE_SELF"}, - {InModify, "IN_MODIFY"}, - {InMove, "IN_MOVE"}, - {InMovedFrom, "IN_MOVED_FROM"}, - {InMovedTo, "IN_MOVED_TO"}, - {InMoveSelf, "IN_MOVE_SELF"}, - {InOpen, "IN_OPEN"}, - {InIsdir, "IN_ISDIR"}, - {InIgnored, "IN_IGNORED"}, - {InQOverflow, "IN_Q_OVERFLOW"}, - {InUnmount, "IN_UNMOUNT"}, -} diff --git a/vendor/k8s.io/utils/inotify/inotify_others.go b/vendor/k8s.io/utils/inotify/inotify_others.go deleted file mode 100644 index 729764404..000000000 --- a/vendor/k8s.io/utils/inotify/inotify_others.go +++ /dev/null @@ -1,54 +0,0 @@ -// +build !linux - -/* -Copyright 2020 The Kubernetes Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package inotify // import "k8s.io/utils/inotify" - -import ( - "fmt" - "runtime" -) - -var errNotSupported = fmt.Errorf("watch not supported on %s", runtime.GOOS) - -// NewWatcher creates and returns a new inotify instance using inotify_init(2) -func NewWatcher() (*Watcher, error) { - return nil, errNotSupported -} - -// Close closes an inotify watcher instance -// It sends a message to the reader goroutine to quit and removes all watches -// associated with the inotify instance -func (w *Watcher) Close() error { - return errNotSupported -} - -// AddWatch adds path to the watched file set. -// The flags are interpreted as described in inotify_add_watch(2). -func (w *Watcher) AddWatch(path string, flags uint32) error { - return errNotSupported -} - -// Watch adds path to the watched file set, watching all events. -func (w *Watcher) Watch(path string) error { - return errNotSupported -} - -// RemoveWatch removes path from the watched file set. -func (w *Watcher) RemoveWatch(path string) error { - return errNotSupported -} diff --git a/vendor/modules.txt b/vendor/modules.txt index ecb24dcaf..dafec569a 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,5 +1,5 @@ -# cel.dev/expr v0.19.1 -## explicit; go 1.21.1 +# cel.dev/expr v0.24.0 +## explicit; go 1.22.0 cel.dev/expr # cyphar.com/go-pathrs v0.2.1 ## explicit; go 1.18 @@ -148,19 +148,9 @@ github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/shared github.com/AzureAD/microsoft-authentication-library-for-go/apps/internal/version github.com/AzureAD/microsoft-authentication-library-for-go/apps/managedidentity github.com/AzureAD/microsoft-authentication-library-for-go/apps/public -# github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab -## explicit -github.com/JeffAshton/win_pdh # github.com/Masterminds/semver/v3 v3.4.0 ## explicit; go 1.21 github.com/Masterminds/semver/v3 -# github.com/Microsoft/go-winio v0.6.2 -## explicit; go 1.21 -github.com/Microsoft/go-winio -github.com/Microsoft/go-winio/internal/fs -github.com/Microsoft/go-winio/internal/socket -github.com/Microsoft/go-winio/internal/stringbuffer -github.com/Microsoft/go-winio/pkg/guid # github.com/antlr4-go/antlr/v4 v4.13.1 ## explicit; go 1.22 github.com/antlr4-go/antlr/v4 @@ -179,36 +169,8 @@ github.com/cespare/xxhash/v2 # github.com/container-storage-interface/spec v1.12.0 ## explicit; go 1.23.0 github.com/container-storage-interface/spec/lib/go/csi -# github.com/containerd/containerd/api v1.8.0 -## explicit; go 1.21 -github.com/containerd/containerd/api/services/containers/v1 -github.com/containerd/containerd/api/services/tasks/v1 -github.com/containerd/containerd/api/services/version/v1 -github.com/containerd/containerd/api/types -github.com/containerd/containerd/api/types/task -# github.com/containerd/errdefs v1.0.0 -## explicit; go 1.20 -github.com/containerd/errdefs -# github.com/containerd/errdefs/pkg v0.3.0 -## explicit; go 1.22 -github.com/containerd/errdefs/pkg/errgrpc -github.com/containerd/errdefs/pkg/internal/cause -github.com/containerd/errdefs/pkg/internal/types -# github.com/containerd/log v0.1.0 -## explicit; go 1.20 -github.com/containerd/log -# github.com/containerd/ttrpc v1.2.6 -## explicit; go 1.19 -github.com/containerd/ttrpc -# github.com/containerd/typeurl/v2 v2.2.2 -## explicit; go 1.21 -github.com/containerd/typeurl/v2 -# github.com/coreos/go-systemd/v22 v22.5.0 -## explicit; go 1.12 -github.com/coreos/go-systemd/v22/dbus # github.com/cyphar/filepath-securejoin v0.6.0 ## explicit; go 1.18 -github.com/cyphar/filepath-securejoin github.com/cyphar/filepath-securejoin/internal/consts github.com/cyphar/filepath-securejoin/pathrs-lite github.com/cyphar/filepath-securejoin/pathrs-lite/internal @@ -226,16 +188,10 @@ github.com/davecgh/go-spew/spew # github.com/distribution/reference v0.6.0 ## explicit; go 1.20 github.com/distribution/reference -# github.com/docker/go-units v0.5.0 -## explicit -github.com/docker/go-units -# github.com/emicklei/go-restful/v3 v3.12.1 +# github.com/emicklei/go-restful/v3 v3.12.2 ## explicit; go 1.13 github.com/emicklei/go-restful/v3 github.com/emicklei/go-restful/v3/log -# github.com/euank/go-kmsg-parser v2.0.0+incompatible -## explicit -github.com/euank/go-kmsg-parser/kmsgparser # github.com/felixge/httpsnoop v1.0.4 ## explicit; go 1.13 github.com/felixge/httpsnoop @@ -243,8 +199,8 @@ github.com/felixge/httpsnoop ## explicit; go 1.17 github.com/fsnotify/fsnotify github.com/fsnotify/fsnotify/internal -# github.com/fxamacker/cbor/v2 v2.7.0 -## explicit; go 1.17 +# github.com/fxamacker/cbor/v2 v2.9.0 +## explicit; go 1.20 github.com/fxamacker/cbor/v2 # github.com/go-ini/ini v1.67.0 ## explicit @@ -269,17 +225,12 @@ github.com/go-openapi/swag # github.com/go-task/slim-sprig/v3 v3.0.0 ## explicit; go 1.20 github.com/go-task/slim-sprig/v3 -# github.com/godbus/dbus/v5 v5.1.0 -## explicit; go 1.12 -github.com/godbus/dbus/v5 # github.com/gofrs/uuid v4.4.0+incompatible ## explicit github.com/gofrs/uuid # github.com/gogo/protobuf v1.3.2 ## explicit; go 1.15 -github.com/gogo/protobuf/gogoproto github.com/gogo/protobuf/proto -github.com/gogo/protobuf/protoc-gen-gogo/descriptor github.com/gogo/protobuf/sortkeys # github.com/golang-jwt/jwt/v4 v4.5.2 ## explicit; go 1.16 @@ -293,48 +244,8 @@ github.com/golang/protobuf/descriptor github.com/golang/protobuf/proto github.com/golang/protobuf/protoc-gen-go/descriptor github.com/golang/protobuf/ptypes/wrappers -# github.com/google/cadvisor v0.52.1 -## explicit; go 1.23.0 -github.com/google/cadvisor/cache/memory -github.com/google/cadvisor/collector -github.com/google/cadvisor/container -github.com/google/cadvisor/container/common -github.com/google/cadvisor/container/containerd -github.com/google/cadvisor/container/containerd/containers -github.com/google/cadvisor/container/containerd/identifiers -github.com/google/cadvisor/container/containerd/install -github.com/google/cadvisor/container/containerd/namespaces -github.com/google/cadvisor/container/containerd/pkg/dialer -github.com/google/cadvisor/container/crio -github.com/google/cadvisor/container/crio/install -github.com/google/cadvisor/container/libcontainer -github.com/google/cadvisor/container/raw -github.com/google/cadvisor/container/systemd -github.com/google/cadvisor/container/systemd/install -github.com/google/cadvisor/devicemapper -github.com/google/cadvisor/events -github.com/google/cadvisor/fs -github.com/google/cadvisor/info/v1 -github.com/google/cadvisor/info/v2 -github.com/google/cadvisor/machine -github.com/google/cadvisor/manager -github.com/google/cadvisor/nvm -github.com/google/cadvisor/perf -github.com/google/cadvisor/resctrl -github.com/google/cadvisor/stats -github.com/google/cadvisor/storage -github.com/google/cadvisor/summary -github.com/google/cadvisor/utils -github.com/google/cadvisor/utils/cloudinfo -github.com/google/cadvisor/utils/cpuload -github.com/google/cadvisor/utils/cpuload/netlink -github.com/google/cadvisor/utils/oomparser -github.com/google/cadvisor/utils/sysfs -github.com/google/cadvisor/utils/sysinfo -github.com/google/cadvisor/version -github.com/google/cadvisor/watcher -# github.com/google/cel-go v0.23.2 -## explicit; go 1.21.1 +# github.com/google/cel-go v0.26.0 +## explicit; go 1.22.0 github.com/google/cel-go/cel github.com/google/cel-go/checker github.com/google/cel-go/checker/decls @@ -343,6 +254,7 @@ github.com/google/cel-go/common/ast github.com/google/cel-go/common/containers github.com/google/cel-go/common/debug github.com/google/cel-go/common/decls +github.com/google/cel-go/common/env github.com/google/cel-go/common/functions github.com/google/cel-go/common/operators github.com/google/cel-go/common/overloads @@ -357,8 +269,8 @@ github.com/google/cel-go/interpreter github.com/google/cel-go/interpreter/functions github.com/google/cel-go/parser github.com/google/cel-go/parser/gen -# github.com/google/gnostic-models v0.6.9 -## explicit; go 1.21 +# github.com/google/gnostic-models v0.7.0 +## explicit; go 1.22 github.com/google/gnostic-models/compiler github.com/google/gnostic-models/extensions github.com/google/gnostic-models/jsonschema @@ -367,7 +279,6 @@ github.com/google/gnostic-models/openapiv3 # github.com/google/go-cmp v0.7.0 ## explicit; go 1.21 github.com/google/go-cmp/cmp -github.com/google/go-cmp/cmp/cmpopts github.com/google/go-cmp/cmp/internal/diff github.com/google/go-cmp/cmp/internal/flags github.com/google/go-cmp/cmp/internal/function @@ -384,11 +295,11 @@ github.com/gorilla/websocket # github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.1.0 ## explicit; go 1.21 github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus -# github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.1.0 -## explicit; go 1.19 +# github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 +## explicit; go 1.23 github.com/grpc-ecosystem/go-grpc-middleware/v2/interceptors -# github.com/grpc-ecosystem/grpc-gateway/v2 v2.24.0 -## explicit; go 1.22.7 +# github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 +## explicit; go 1.23.0 github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule github.com/grpc-ecosystem/grpc-gateway/v2/runtime github.com/grpc-ecosystem/grpc-gateway/v2/utilities @@ -401,9 +312,6 @@ github.com/josharian/intern # github.com/json-iterator/go v1.1.12 ## explicit; go 1.12 github.com/json-iterator/go -# github.com/karrick/godirwalk v1.17.0 -## explicit; go 1.13 -github.com/karrick/godirwalk # github.com/kubernetes-csi/csi-lib-utils v0.16.0 ## explicit; go 1.18 github.com/kubernetes-csi/csi-lib-utils/protosanitizer @@ -416,9 +324,6 @@ github.com/kylelemons/godebug/pretty github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter -# github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible -## explicit -github.com/mistifyio/go-zfs # github.com/moby/spdystream v0.5.0 ## explicit; go 1.13 github.com/moby/spdystream @@ -426,13 +331,10 @@ github.com/moby/spdystream/spdy # github.com/moby/sys/mountinfo v0.7.2 ## explicit; go 1.17 github.com/moby/sys/mountinfo -# github.com/moby/sys/userns v0.1.0 -## explicit; go 1.21 -github.com/moby/sys/userns # github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd ## explicit github.com/modern-go/concurrent -# github.com/modern-go/reflect2 v1.0.2 +# github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee ## explicit; go 1.12 github.com/modern-go/reflect2 # github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 @@ -479,26 +381,9 @@ github.com/onsi/gomega/matchers/support/goraph/edge github.com/onsi/gomega/matchers/support/goraph/node github.com/onsi/gomega/matchers/support/goraph/util github.com/onsi/gomega/types -# github.com/opencontainers/cgroups v0.0.1 -## explicit; go 1.23.0 -github.com/opencontainers/cgroups -github.com/opencontainers/cgroups/devices/config -github.com/opencontainers/cgroups/fs -github.com/opencontainers/cgroups/fs2 -github.com/opencontainers/cgroups/fscommon -github.com/opencontainers/cgroups/internal/path -github.com/opencontainers/cgroups/manager -github.com/opencontainers/cgroups/systemd # github.com/opencontainers/go-digest v1.0.0 ## explicit; go 1.13 github.com/opencontainers/go-digest -# github.com/opencontainers/image-spec v1.1.1 -## explicit; go 1.18 -github.com/opencontainers/image-spec/specs-go -github.com/opencontainers/image-spec/specs-go/v1 -# github.com/opencontainers/runtime-spec v1.2.0 -## explicit -github.com/opencontainers/runtime-spec/specs-go # github.com/opencontainers/selinux v1.13.0 ## explicit; go 1.19 github.com/opencontainers/selinux/go-selinux @@ -546,9 +431,6 @@ github.com/samber/lo github.com/samber/lo/internal/constraints github.com/samber/lo/internal/rand github.com/samber/lo/mutable -# github.com/sirupsen/logrus v1.9.3 -## explicit; go 1.13 -github.com/sirupsen/logrus # github.com/spf13/cobra v1.9.1 ## explicit; go 1.15 github.com/spf13/cobra @@ -570,10 +452,6 @@ github.com/x448/float16 ## explicit; go 1.22.0 go.opentelemetry.io/auto/sdk go.opentelemetry.io/auto/sdk/internal/telemetry -# go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 -## explicit; go 1.22.7 -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc/internal # go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 ## explicit; go 1.22.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp @@ -594,12 +472,12 @@ go.opentelemetry.io/otel/semconv/v1.17.0 go.opentelemetry.io/otel/semconv/v1.20.0 go.opentelemetry.io/otel/semconv/v1.26.0 go.opentelemetry.io/otel/semconv/v1.34.0 -# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 -## explicit; go 1.22.7 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 +## explicit; go 1.22.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace go.opentelemetry.io/otel/exporters/otlp/otlptrace/internal/tracetransform -# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 -## explicit; go 1.22.7 +# go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 +## explicit; go 1.22.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc/internal/envconfig @@ -635,8 +513,8 @@ go.opentelemetry.io/otel/trace go.opentelemetry.io/otel/trace/embedded go.opentelemetry.io/otel/trace/internal/telemetry go.opentelemetry.io/otel/trace/noop -# go.opentelemetry.io/proto/otlp v1.4.0 -## explicit; go 1.22.7 +# go.opentelemetry.io/proto/otlp v1.5.0 +## explicit; go 1.22.0 go.opentelemetry.io/proto/otlp/collector/trace/v1 go.opentelemetry.io/proto/otlp/common/v1 go.opentelemetry.io/proto/otlp/resource/v1 @@ -761,21 +639,22 @@ golang.org/x/tools/internal/stdlib golang.org/x/tools/internal/typeparams golang.org/x/tools/internal/typesinternal golang.org/x/tools/internal/versions -# google.golang.org/genproto/googleapis/api v0.0.0-20241209162323-e6fa225c2576 -## explicit; go 1.21 +# google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb +## explicit; go 1.23.0 google.golang.org/genproto/googleapis/api/expr/v1alpha1 google.golang.org/genproto/googleapis/api/httpbody -# google.golang.org/genproto/googleapis/rpc v0.0.0-20241209162323-e6fa225c2576 -## explicit; go 1.21 +# google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb +## explicit; go 1.23.0 google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.68.1 -## explicit; go 1.22 +# google.golang.org/grpc v1.72.1 +## explicit; go 1.23 google.golang.org/grpc google.golang.org/grpc/attributes google.golang.org/grpc/backoff google.golang.org/grpc/balancer google.golang.org/grpc/balancer/base +google.golang.org/grpc/balancer/endpointsharding google.golang.org/grpc/balancer/grpclb/state google.golang.org/grpc/balancer/pickfirst google.golang.org/grpc/balancer/pickfirst/internal @@ -809,7 +688,9 @@ google.golang.org/grpc/internal/grpcutil google.golang.org/grpc/internal/idle google.golang.org/grpc/internal/metadata google.golang.org/grpc/internal/pretty +google.golang.org/grpc/internal/proxyattributes google.golang.org/grpc/internal/resolver +google.golang.org/grpc/internal/resolver/delegatingresolver google.golang.org/grpc/internal/resolver/dns google.golang.org/grpc/internal/resolver/dns/internal google.golang.org/grpc/internal/resolver/passthrough @@ -1066,18 +947,12 @@ k8s.io/apiserver/pkg/cel/library k8s.io/apiserver/pkg/cel/mutation k8s.io/apiserver/pkg/cel/mutation/dynamic k8s.io/apiserver/pkg/cel/openapi/resolver -k8s.io/apiserver/pkg/endpoints/metrics k8s.io/apiserver/pkg/endpoints/openapi k8s.io/apiserver/pkg/endpoints/request -k8s.io/apiserver/pkg/endpoints/responsewriter k8s.io/apiserver/pkg/features k8s.io/apiserver/pkg/quota/v1 k8s.io/apiserver/pkg/server/egressselector k8s.io/apiserver/pkg/server/egressselector/metrics -k8s.io/apiserver/pkg/server/healthz -k8s.io/apiserver/pkg/server/httplog -k8s.io/apiserver/pkg/server/routine -k8s.io/apiserver/pkg/storage k8s.io/apiserver/pkg/storage/names k8s.io/apiserver/pkg/util/compatibility k8s.io/apiserver/pkg/util/feature @@ -1144,8 +1019,6 @@ k8s.io/client-go/discovery k8s.io/client-go/discovery/cached/memory k8s.io/client-go/discovery/fake k8s.io/client-go/dynamic -k8s.io/client-go/dynamic/dynamicinformer -k8s.io/client-go/dynamic/dynamiclister k8s.io/client-go/features k8s.io/client-go/gentype k8s.io/client-go/informers @@ -1412,7 +1285,6 @@ k8s.io/client-go/tools/clientcmd k8s.io/client-go/tools/clientcmd/api k8s.io/client-go/tools/clientcmd/api/latest k8s.io/client-go/tools/clientcmd/api/v1 -k8s.io/client-go/tools/events k8s.io/client-go/tools/internal/events k8s.io/client-go/tools/metrics k8s.io/client-go/tools/pager @@ -1442,26 +1314,19 @@ k8s.io/cloud-provider k8s.io/cloud-provider/api k8s.io/cloud-provider/node/helpers k8s.io/cloud-provider/service/helpers -k8s.io/cloud-provider/volume -k8s.io/cloud-provider/volume/helpers # k8s.io/component-base v0.33.4 => k8s.io/component-base v0.33.4 ## explicit; go 1.24.0 k8s.io/component-base/cli/flag k8s.io/component-base/compatibility -k8s.io/component-base/config -k8s.io/component-base/config/v1alpha1 -k8s.io/component-base/config/validation k8s.io/component-base/featuregate k8s.io/component-base/logs k8s.io/component-base/logs/api/v1 k8s.io/component-base/logs/internal/setverbositylevel k8s.io/component-base/logs/klogflags -k8s.io/component-base/logs/logreduction k8s.io/component-base/logs/testinit k8s.io/component-base/metrics k8s.io/component-base/metrics/legacyregistry k8s.io/component-base/metrics/prometheus/feature -k8s.io/component-base/metrics/prometheus/slis k8s.io/component-base/metrics/prometheusextension k8s.io/component-base/metrics/testutil k8s.io/component-base/tracing @@ -1470,39 +1335,14 @@ k8s.io/component-base/version k8s.io/component-base/zpages/features # k8s.io/component-helpers v0.33.4 => k8s.io/component-helpers v0.33.4 ## explicit; go 1.24.0 -k8s.io/component-helpers/node/topology k8s.io/component-helpers/node/util k8s.io/component-helpers/node/util/sysctl k8s.io/component-helpers/resource k8s.io/component-helpers/scheduling/corev1 k8s.io/component-helpers/scheduling/corev1/nodeaffinity -k8s.io/component-helpers/storage/ephemeral -k8s.io/component-helpers/storage/volume # k8s.io/controller-manager v0.33.4 => k8s.io/controller-manager v0.33.4 ## explicit; go 1.24.0 k8s.io/controller-manager/pkg/features -# k8s.io/cri-api v0.33.4 => k8s.io/cri-api v0.33.4 -## explicit; go 1.24.0 -k8s.io/cri-api/pkg/apis -k8s.io/cri-api/pkg/apis/runtime/v1 -# k8s.io/cri-client v0.0.0 => k8s.io/cri-client v0.33.4 -## explicit; go 1.24.0 -k8s.io/cri-client/pkg -k8s.io/cri-client/pkg/internal -k8s.io/cri-client/pkg/logs -k8s.io/cri-client/pkg/util -# k8s.io/csi-translation-lib v0.0.0 => k8s.io/csi-translation-lib v0.33.4 -## explicit; go 1.24.0 -k8s.io/csi-translation-lib -k8s.io/csi-translation-lib/plugins -# k8s.io/dynamic-resource-allocation v0.0.0 => k8s.io/dynamic-resource-allocation v0.33.4 -## explicit; go 1.24.0 -k8s.io/dynamic-resource-allocation/api -k8s.io/dynamic-resource-allocation/cel -k8s.io/dynamic-resource-allocation/internal/queue -k8s.io/dynamic-resource-allocation/resourceclaim -k8s.io/dynamic-resource-allocation/resourceslice/tracker -k8s.io/dynamic-resource-allocation/structured # k8s.io/klog/v2 v2.130.1 ## explicit; go 1.18 k8s.io/klog/v2 @@ -1514,8 +1354,8 @@ k8s.io/klog/v2/internal/severity k8s.io/klog/v2/internal/sloghandler k8s.io/klog/v2/internal/verbosity k8s.io/klog/v2/textlogger -# k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff -## explicit; go 1.21 +# k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b +## explicit; go 1.23 k8s.io/kube-openapi/pkg/cached k8s.io/kube-openapi/pkg/common k8s.io/kube-openapi/pkg/handler3 @@ -1530,10 +1370,6 @@ k8s.io/kube-openapi/pkg/validation/errors k8s.io/kube-openapi/pkg/validation/spec k8s.io/kube-openapi/pkg/validation/strfmt k8s.io/kube-openapi/pkg/validation/strfmt/bson -# k8s.io/kube-scheduler v0.0.0 => k8s.io/kube-scheduler v0.33.4 -## explicit; go 1.24.0 -k8s.io/kube-scheduler/config/v1 -k8s.io/kube-scheduler/extender/v1 # k8s.io/kubectl v0.31.1 => k8s.io/kubectl v0.33.4 ## explicit; go 1.24.0 k8s.io/kubectl/pkg/scale @@ -1541,14 +1377,8 @@ k8s.io/kubectl/pkg/util/podutils # k8s.io/kubelet v0.33.4 => k8s.io/kubelet v0.33.4 ## explicit; go 1.24.0 k8s.io/kubelet/pkg/apis -k8s.io/kubelet/pkg/apis/deviceplugin/v1beta1 -k8s.io/kubelet/pkg/apis/dra/v1alpha4 -k8s.io/kubelet/pkg/apis/dra/v1beta1 -k8s.io/kubelet/pkg/apis/pluginregistration/v1 -k8s.io/kubelet/pkg/apis/podresources/v1 -k8s.io/kubelet/pkg/apis/podresources/v1alpha1 k8s.io/kubelet/pkg/apis/stats/v1alpha1 -# k8s.io/kubernetes v1.33.7 +# k8s.io/kubernetes v1.34.3 ## explicit; go 1.24.0 k8s.io/kubernetes/pkg/api/legacyscheme k8s.io/kubernetes/pkg/api/service @@ -1557,6 +1387,7 @@ k8s.io/kubernetes/pkg/api/v1/service k8s.io/kubernetes/pkg/apis/apps k8s.io/kubernetes/pkg/apis/autoscaling k8s.io/kubernetes/pkg/apis/batch +k8s.io/kubernetes/pkg/apis/certificates k8s.io/kubernetes/pkg/apis/core k8s.io/kubernetes/pkg/apis/core/helper k8s.io/kubernetes/pkg/apis/core/helper/qos @@ -1564,112 +1395,20 @@ k8s.io/kubernetes/pkg/apis/core/install k8s.io/kubernetes/pkg/apis/core/pods k8s.io/kubernetes/pkg/apis/core/v1 k8s.io/kubernetes/pkg/apis/core/v1/helper -k8s.io/kubernetes/pkg/apis/core/v1/helper/qos k8s.io/kubernetes/pkg/apis/core/validation k8s.io/kubernetes/pkg/apis/extensions k8s.io/kubernetes/pkg/apis/networking -k8s.io/kubernetes/pkg/apis/scheduling k8s.io/kubernetes/pkg/capabilities k8s.io/kubernetes/pkg/controller k8s.io/kubernetes/pkg/controller/deployment/util -k8s.io/kubernetes/pkg/credentialprovider k8s.io/kubernetes/pkg/features k8s.io/kubernetes/pkg/fieldpath -k8s.io/kubernetes/pkg/kubelet/apis/config -k8s.io/kubernetes/pkg/kubelet/apis/podresources -k8s.io/kubernetes/pkg/kubelet/cadvisor -k8s.io/kubernetes/pkg/kubelet/checkpointmanager -k8s.io/kubernetes/pkg/kubelet/checkpointmanager/checksum -k8s.io/kubernetes/pkg/kubelet/checkpointmanager/errors -k8s.io/kubernetes/pkg/kubelet/cm -k8s.io/kubernetes/pkg/kubelet/cm/admission -k8s.io/kubernetes/pkg/kubelet/cm/containermap -k8s.io/kubernetes/pkg/kubelet/cm/cpumanager -k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/state -k8s.io/kubernetes/pkg/kubelet/cm/cpumanager/topology -k8s.io/kubernetes/pkg/kubelet/cm/devicemanager -k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/checkpoint -k8s.io/kubernetes/pkg/kubelet/cm/devicemanager/plugin/v1beta1 -k8s.io/kubernetes/pkg/kubelet/cm/dra -k8s.io/kubernetes/pkg/kubelet/cm/dra/plugin -k8s.io/kubernetes/pkg/kubelet/cm/dra/state -k8s.io/kubernetes/pkg/kubelet/cm/memorymanager -k8s.io/kubernetes/pkg/kubelet/cm/memorymanager/state -k8s.io/kubernetes/pkg/kubelet/cm/resourceupdates -k8s.io/kubernetes/pkg/kubelet/cm/topologymanager -k8s.io/kubernetes/pkg/kubelet/cm/topologymanager/bitmask -k8s.io/kubernetes/pkg/kubelet/cm/util -k8s.io/kubernetes/pkg/kubelet/config -k8s.io/kubernetes/pkg/kubelet/container k8s.io/kubernetes/pkg/kubelet/events -k8s.io/kubernetes/pkg/kubelet/eviction/api -k8s.io/kubernetes/pkg/kubelet/kuberuntime/util -k8s.io/kubernetes/pkg/kubelet/lifecycle -k8s.io/kubernetes/pkg/kubelet/metrics -k8s.io/kubernetes/pkg/kubelet/pluginmanager/cache -k8s.io/kubernetes/pkg/kubelet/qos k8s.io/kubernetes/pkg/kubelet/server/metrics -k8s.io/kubernetes/pkg/kubelet/stats/pidlimit -k8s.io/kubernetes/pkg/kubelet/status -k8s.io/kubernetes/pkg/kubelet/types -k8s.io/kubernetes/pkg/kubelet/util -k8s.io/kubernetes/pkg/kubelet/util/format -k8s.io/kubernetes/pkg/kubelet/util/store -k8s.io/kubernetes/pkg/kubelet/util/swap -k8s.io/kubernetes/pkg/kubelet/winstats -k8s.io/kubernetes/pkg/probe -k8s.io/kubernetes/pkg/probe/http -k8s.io/kubernetes/pkg/scheduler -k8s.io/kubernetes/pkg/scheduler/apis/config -k8s.io/kubernetes/pkg/scheduler/apis/config/scheme -k8s.io/kubernetes/pkg/scheduler/apis/config/v1 -k8s.io/kubernetes/pkg/scheduler/apis/config/validation -k8s.io/kubernetes/pkg/scheduler/backend/cache -k8s.io/kubernetes/pkg/scheduler/backend/cache/debugger -k8s.io/kubernetes/pkg/scheduler/backend/heap -k8s.io/kubernetes/pkg/scheduler/backend/queue -k8s.io/kubernetes/pkg/scheduler/framework -k8s.io/kubernetes/pkg/scheduler/framework/parallelize -k8s.io/kubernetes/pkg/scheduler/framework/plugins -k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder -k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpreemption -k8s.io/kubernetes/pkg/scheduler/framework/plugins/dynamicresources -k8s.io/kubernetes/pkg/scheduler/framework/plugins/feature -k8s.io/kubernetes/pkg/scheduler/framework/plugins/helper -k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality -k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity -k8s.io/kubernetes/pkg/scheduler/framework/plugins/names -k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity -k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename -k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeports -k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources -k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable -k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodevolumelimits -k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread -k8s.io/kubernetes/pkg/scheduler/framework/plugins/queuesort -k8s.io/kubernetes/pkg/scheduler/framework/plugins/schedulinggates -k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration -k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding -k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumebinding/metrics -k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumerestrictions -k8s.io/kubernetes/pkg/scheduler/framework/plugins/volumezone -k8s.io/kubernetes/pkg/scheduler/framework/preemption -k8s.io/kubernetes/pkg/scheduler/framework/runtime -k8s.io/kubernetes/pkg/scheduler/metrics -k8s.io/kubernetes/pkg/scheduler/profile -k8s.io/kubernetes/pkg/scheduler/util -k8s.io/kubernetes/pkg/scheduler/util/assumecache -k8s.io/kubernetes/pkg/scheduler/util/queue -k8s.io/kubernetes/pkg/security/apparmor k8s.io/kubernetes/pkg/securitycontext -k8s.io/kubernetes/pkg/util/filesystem k8s.io/kubernetes/pkg/util/hash -k8s.io/kubernetes/pkg/util/kernel k8s.io/kubernetes/pkg/util/labels -k8s.io/kubernetes/pkg/util/oom k8s.io/kubernetes/pkg/util/parsers -k8s.io/kubernetes/pkg/util/pod -k8s.io/kubernetes/pkg/util/slice k8s.io/kubernetes/pkg/util/taints k8s.io/kubernetes/pkg/volume k8s.io/kubernetes/pkg/volume/util @@ -1706,10 +1445,7 @@ k8s.io/kubernetes/test/utils k8s.io/kubernetes/test/utils/format k8s.io/kubernetes/test/utils/image k8s.io/kubernetes/test/utils/kubeconfig -k8s.io/kubernetes/third_party/forked/golang/expansion -k8s.io/kubernetes/third_party/forked/libcontainer/apparmor -k8s.io/kubernetes/third_party/forked/libcontainer/utils -# k8s.io/mount-utils v0.34.2 +# k8s.io/mount-utils v0.34.3 ## explicit; go 1.24.0 k8s.io/mount-utils # k8s.io/pod-security-admission v0.31.1 => k8s.io/pod-security-admission v0.33.4 @@ -1720,10 +1456,8 @@ k8s.io/pod-security-admission/policy ## explicit; go 1.18 k8s.io/utils/buffer k8s.io/utils/clock -k8s.io/utils/cpuset k8s.io/utils/exec k8s.io/utils/exec/testing -k8s.io/utils/inotify k8s.io/utils/integer k8s.io/utils/internal/third_party/forked/golang/golang-lru k8s.io/utils/internal/third_party/forked/golang/net @@ -1866,8 +1600,8 @@ sigs.k8s.io/cloud-provider-azure/pkg/azclient/cache # sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader v0.7.2 ## explicit; go 1.24.0 sigs.k8s.io/cloud-provider-azure/pkg/azclient/configloader -# sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 -## explicit; go 1.21 +# sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 +## explicit; go 1.23 sigs.k8s.io/json sigs.k8s.io/json/internal/golang/encoding/json # sigs.k8s.io/randfill v1.0.0 @@ -1881,6 +1615,9 @@ sigs.k8s.io/structured-merge-diff/v4/merge sigs.k8s.io/structured-merge-diff/v4/schema sigs.k8s.io/structured-merge-diff/v4/typed sigs.k8s.io/structured-merge-diff/v4/value +# sigs.k8s.io/structured-merge-diff/v6 v6.3.0 +## explicit; go 1.23 +sigs.k8s.io/structured-merge-diff/v6/schema # sigs.k8s.io/yaml v1.6.0 ## explicit; go 1.22 sigs.k8s.io/yaml diff --git a/vendor/github.com/euank/go-kmsg-parser/LICENSE b/vendor/sigs.k8s.io/structured-merge-diff/v6/LICENSE similarity index 100% rename from vendor/github.com/euank/go-kmsg-parser/LICENSE rename to vendor/sigs.k8s.io/structured-merge-diff/v6/LICENSE diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/doc.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/doc.go new file mode 100644 index 000000000..9081ccbc7 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/doc.go @@ -0,0 +1,28 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package schema defines a targeted schema language which allows one to +// represent all the schema information necessary to perform "structured" +// merges and diffs. +// +// Due to the targeted nature of the data model, the schema language can fit in +// just a few hundred lines of go code, making it much more understandable and +// concise than e.g. OpenAPI. +// +// This schema was derived by observing the API objects used by Kubernetes, and +// formalizing a model which allows certain operations ("apply") to be more +// well defined. It is currently missing one feature: one-of ("unions"). +package schema diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go new file mode 100644 index 000000000..5d3707a5b --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/elements.go @@ -0,0 +1,375 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package schema + +import ( + "sync" +) + +// Schema is a list of named types. +// +// Schema types are indexed in a map before the first search so this type +// should be considered immutable. +type Schema struct { + Types []TypeDef `yaml:"types,omitempty"` + + once sync.Once + m map[string]TypeDef + + lock sync.Mutex + // Cached results of resolving type references to atoms. Only stores + // type references which require fields of Atom to be overriden. + resolvedTypes map[TypeRef]Atom +} + +// A TypeSpecifier references a particular type in a schema. +type TypeSpecifier struct { + Type TypeRef `yaml:"type,omitempty"` + Schema Schema `yaml:"schema,omitempty"` +} + +// TypeDef represents a named type in a schema. +type TypeDef struct { + // Top level types should be named. Every type must have a unique name. + Name string `yaml:"name,omitempty"` + + Atom `yaml:"atom,omitempty,inline"` +} + +// TypeRef either refers to a named type or declares an inlined type. +type TypeRef struct { + // Either the name or one member of Atom should be set. + NamedType *string `yaml:"namedType,omitempty"` + Inlined Atom `yaml:",inline,omitempty"` + + // If this reference refers to a map-type or list-type, this field overrides + // the `ElementRelationship` of the referred type when resolved. + // If this field is nil, then it has no effect. + // See `Map` and `List` for more information about `ElementRelationship` + ElementRelationship *ElementRelationship `yaml:"elementRelationship,omitempty"` +} + +// Atom represents the smallest possible pieces of the type system. +// Each set field in the Atom represents a possible type for the object. +// If none of the fields are set, any object will fail validation against the atom. +type Atom struct { + *Scalar `yaml:"scalar,omitempty"` + *List `yaml:"list,omitempty"` + *Map `yaml:"map,omitempty"` +} + +// Scalar (AKA "primitive") represents a type which has a single value which is +// either numeric, string, or boolean, or untyped for any of them. +// +// TODO: split numeric into float/int? Something even more fine-grained? +type Scalar string + +const ( + Numeric = Scalar("numeric") + String = Scalar("string") + Boolean = Scalar("boolean") + Untyped = Scalar("untyped") +) + +// ElementRelationship is an enum of the different possible relationships +// between the elements of container types (maps, lists). +type ElementRelationship string + +const ( + // Associative only applies to lists (see the documentation there). + Associative = ElementRelationship("associative") + // Atomic makes container types (lists, maps) behave + // as scalars / leaf fields + Atomic = ElementRelationship("atomic") + // Separable means the items of the container type have no particular + // relationship (default behavior for maps). + Separable = ElementRelationship("separable") +) + +// Map is a key-value pair. Its default semantics are the same as an +// associative list, but: +// - It is serialized differently: +// map: {"k": {"value": "v"}} +// list: [{"key": "k", "value": "v"}] +// - Keys must be string typed. +// - Keys can't have multiple components. +// +// Optionally, maps may be atomic (for example, imagine representing an RGB +// color value--it doesn't make sense to have different actors own the R and G +// values). +// +// Maps may also represent a type which is composed of a number of different fields. +// Each field has a name and a type. +// +// Fields are indexed in a map before the first search so this type +// should be considered immutable. +type Map struct { + // Each struct field appears exactly once in this list. The order in + // this list defines the canonical field ordering. + Fields []StructField `yaml:"fields,omitempty"` + + // A Union is a grouping of fields with special rules. It may refer to + // one or more fields in the above list. A given field from the above + // list may be referenced in exactly 0 or 1 places in the below list. + // One can have multiple unions in the same struct, but the fields can't + // overlap between unions. + Unions []Union `yaml:"unions,omitempty"` + + // ElementType is the type of the structs's unknown fields. + ElementType TypeRef `yaml:"elementType,omitempty"` + + // ElementRelationship states the relationship between the map's items. + // * `separable` (or unset) implies that each element is 100% independent. + // * `atomic` implies that all elements depend on each other, and this + // is effectively a scalar / leaf field; it doesn't make sense for + // separate actors to set the elements. Example: an RGB color struct; + // it would never make sense to "own" only one component of the + // color. + // The default behavior for maps is `separable`; it's permitted to + // leave this unset to get the default behavior. + ElementRelationship ElementRelationship `yaml:"elementRelationship,omitempty"` + + once sync.Once + m map[string]StructField +} + +// FindField is a convenience function that returns the referenced StructField, +// if it exists, or (nil, false) if it doesn't. +func (m *Map) FindField(name string) (StructField, bool) { + m.once.Do(func() { + m.m = make(map[string]StructField, len(m.Fields)) + for _, field := range m.Fields { + m.m[field.Name] = field + } + }) + sf, ok := m.m[name] + return sf, ok +} + +// CopyInto this instance of Map into the other +// If other is nil this method does nothing. +// If other is already initialized, overwrites it with this instance +// Warning: Not thread safe +func (m *Map) CopyInto(dst *Map) { + if dst == nil { + return + } + + // Map type is considered immutable so sharing references + dst.Fields = m.Fields + dst.ElementType = m.ElementType + dst.Unions = m.Unions + dst.ElementRelationship = m.ElementRelationship + + if m.m != nil { + // If cache is non-nil then the once token had been consumed. + // Must reset token and use it again to ensure same semantics. + dst.once = sync.Once{} + dst.once.Do(func() { + dst.m = m.m + }) + } +} + +// UnionFields are mapping between the fields that are part of the union and +// their discriminated value. The discriminated value has to be set, and +// should not conflict with other discriminated value in the list. +type UnionField struct { + // FieldName is the name of the field that is part of the union. This + // is the serialized form of the field. + FieldName string `yaml:"fieldName"` + // Discriminatorvalue is the value of the discriminator to + // select that field. If the union doesn't have a discriminator, + // this field is ignored. + DiscriminatorValue string `yaml:"discriminatorValue"` +} + +// Union, or oneof, means that only one of multiple fields of a structure can be +// set at a time. Setting the discriminator helps clearing oher fields: +// - If discriminator changed to non-nil, and a new field has been added +// that doesn't match, an error is returned, +// - If discriminator hasn't changed and two fields or more are set, an +// error is returned, +// - If discriminator changed to non-nil, all other fields but the +// discriminated one will be cleared, +// - Otherwise, If only one field is left, update discriminator to that value. +type Union struct { + // Discriminator, if present, is the name of the field that + // discriminates fields in the union. The mapping between the value of + // the discriminator and the field is done by using the Fields list + // below. + Discriminator *string `yaml:"discriminator,omitempty"` + + // DeduceInvalidDiscriminator indicates if the discriminator + // should be updated automatically based on the fields set. This + // typically defaults to false since we don't want to deduce by + // default (the behavior exists to maintain compatibility on + // existing types and shouldn't be used for new types). + DeduceInvalidDiscriminator bool `yaml:"deduceInvalidDiscriminator,omitempty"` + + // This is the list of fields that belong to this union. All the + // fields present in here have to be part of the parent + // structure. Discriminator (if oneOf has one), is NOT included in + // this list. The value for field is how we map the name of the field + // to actual value for discriminator. + Fields []UnionField `yaml:"fields,omitempty"` +} + +// StructField pairs a field name with a field type. +type StructField struct { + // Name is the field name. + Name string `yaml:"name,omitempty"` + // Type is the field type. + Type TypeRef `yaml:"type,omitempty"` + // Default value for the field, nil if not present. + Default interface{} `yaml:"default,omitempty"` +} + +// List represents a type which contains a zero or more elements, all of the +// same subtype. Lists may be either associative: each element is more or less +// independent and could be managed by separate entities in the system; or +// atomic, where the elements are heavily dependent on each other: it is not +// sensible to change one element without considering the ramifications on all +// the other elements. +type List struct { + // ElementType is the type of the list's elements. + ElementType TypeRef `yaml:"elementType,omitempty"` + + // ElementRelationship states the relationship between the list's elements + // and must have one of these values: + // * `atomic`: the list is treated as a single entity, like a scalar. + // * `associative`: + // - If the list element is a scalar, the list is treated as a set. + // - If the list element is a map, the list is treated as a map. + // There is no default for this value for lists; all schemas must + // explicitly state the element relationship for all lists. + ElementRelationship ElementRelationship `yaml:"elementRelationship,omitempty"` + + // Iff ElementRelationship is `associative`, and the element type is + // map, then Keys must have non-zero length, and it lists the fields + // of the element's map type which are to be used as the keys of the + // list. + // + // TODO: change this to "non-atomic struct" above and make the code reflect this. + // + // Each key must refer to a single field name (no nesting, not JSONPath). + Keys []string `yaml:"keys,omitempty"` +} + +// FindNamedType is a convenience function that returns the referenced TypeDef, +// if it exists, or (nil, false) if it doesn't. +func (s *Schema) FindNamedType(name string) (TypeDef, bool) { + s.once.Do(func() { + s.m = make(map[string]TypeDef, len(s.Types)) + for _, t := range s.Types { + s.m[t.Name] = t + } + }) + t, ok := s.m[name] + return t, ok +} + +func (s *Schema) resolveNoOverrides(tr TypeRef) (Atom, bool) { + result := Atom{} + + if tr.NamedType != nil { + t, ok := s.FindNamedType(*tr.NamedType) + if !ok { + return Atom{}, false + } + + result = t.Atom + } else { + result = tr.Inlined + } + + return result, true +} + +// Resolve is a convenience function which returns the atom referenced, whether +// it is inline or named. Returns (Atom{}, false) if the type can't be resolved. +// +// This allows callers to not care about the difference between a (possibly +// inlined) reference and a definition. +func (s *Schema) Resolve(tr TypeRef) (Atom, bool) { + // If this is a plain reference with no overrides, just return the type + if tr.ElementRelationship == nil { + return s.resolveNoOverrides(tr) + } + + s.lock.Lock() + defer s.lock.Unlock() + + if s.resolvedTypes == nil { + s.resolvedTypes = make(map[TypeRef]Atom) + } + + var result Atom + var exists bool + + // Return cached result if available + // If not, calculate result and cache it + if result, exists = s.resolvedTypes[tr]; !exists { + if result, exists = s.resolveNoOverrides(tr); exists { + // Allow field-level electives to override the referred type's modifiers + switch { + case result.Map != nil: + mapCopy := Map{} + result.Map.CopyInto(&mapCopy) + mapCopy.ElementRelationship = *tr.ElementRelationship + result.Map = &mapCopy + case result.List != nil: + listCopy := *result.List + listCopy.ElementRelationship = *tr.ElementRelationship + result.List = &listCopy + case result.Scalar != nil: + return Atom{}, false + default: + return Atom{}, false + } + } else { + return Atom{}, false + } + + // Save result. If it is nil, that is also recorded as not existing. + s.resolvedTypes[tr] = result + } + + return result, true +} + +// Clones this instance of Schema into the other +// If other is nil this method does nothing. +// If other is already initialized, overwrites it with this instance +// Warning: Not thread safe +func (s *Schema) CopyInto(dst *Schema) { + if dst == nil { + return + } + + // Schema type is considered immutable so sharing references + dst.Types = s.Types + + if s.m != nil { + // If cache is non-nil then the once token had been consumed. + // Must reset token and use it again to ensure same semantics. + dst.once = sync.Once{} + dst.once.Do(func() { + dst.m = s.m + }) + } +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go new file mode 100644 index 000000000..b668eff83 --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/equals.go @@ -0,0 +1,202 @@ +/* +Copyright 2019 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package schema + +import "reflect" + +// Equals returns true iff the two Schemas are equal. +func (a *Schema) Equals(b *Schema) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + + if len(a.Types) != len(b.Types) { + return false + } + for i := range a.Types { + if !a.Types[i].Equals(&b.Types[i]) { + return false + } + } + return true +} + +// Equals returns true iff the two TypeRefs are equal. +// +// Note that two typerefs that have an equivalent type but where one is +// inlined and the other is named, are not considered equal. +func (a *TypeRef) Equals(b *TypeRef) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if (a.NamedType == nil) != (b.NamedType == nil) { + return false + } + if a.NamedType != nil { + if *a.NamedType != *b.NamedType { + return false + } + //return true + } + if a.ElementRelationship != b.ElementRelationship { + return false + } + return a.Inlined.Equals(&b.Inlined) +} + +// Equals returns true iff the two TypeDefs are equal. +func (a *TypeDef) Equals(b *TypeDef) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if a.Name != b.Name { + return false + } + return a.Atom.Equals(&b.Atom) +} + +// Equals returns true iff the two Atoms are equal. +func (a *Atom) Equals(b *Atom) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if (a.Scalar == nil) != (b.Scalar == nil) { + return false + } + if (a.List == nil) != (b.List == nil) { + return false + } + if (a.Map == nil) != (b.Map == nil) { + return false + } + switch { + case a.Scalar != nil: + return *a.Scalar == *b.Scalar + case a.List != nil: + return a.List.Equals(b.List) + case a.Map != nil: + return a.Map.Equals(b.Map) + } + return true +} + +// Equals returns true iff the two Maps are equal. +func (a *Map) Equals(b *Map) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if !a.ElementType.Equals(&b.ElementType) { + return false + } + if a.ElementRelationship != b.ElementRelationship { + return false + } + if len(a.Fields) != len(b.Fields) { + return false + } + for i := range a.Fields { + if !a.Fields[i].Equals(&b.Fields[i]) { + return false + } + } + if len(a.Unions) != len(b.Unions) { + return false + } + for i := range a.Unions { + if !a.Unions[i].Equals(&b.Unions[i]) { + return false + } + } + return true +} + +// Equals returns true iff the two Unions are equal. +func (a *Union) Equals(b *Union) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if (a.Discriminator == nil) != (b.Discriminator == nil) { + return false + } + if a.Discriminator != nil { + if *a.Discriminator != *b.Discriminator { + return false + } + } + if a.DeduceInvalidDiscriminator != b.DeduceInvalidDiscriminator { + return false + } + if len(a.Fields) != len(b.Fields) { + return false + } + for i := range a.Fields { + if !a.Fields[i].Equals(&b.Fields[i]) { + return false + } + } + return true +} + +// Equals returns true iff the two UnionFields are equal. +func (a *UnionField) Equals(b *UnionField) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if a.FieldName != b.FieldName { + return false + } + if a.DiscriminatorValue != b.DiscriminatorValue { + return false + } + return true +} + +// Equals returns true iff the two StructFields are equal. +func (a *StructField) Equals(b *StructField) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if a.Name != b.Name { + return false + } + if !reflect.DeepEqual(a.Default, b.Default) { + return false + } + return a.Type.Equals(&b.Type) +} + +// Equals returns true iff the two Lists are equal. +func (a *List) Equals(b *List) bool { + if a == nil || b == nil { + return a == nil && b == nil + } + if !a.ElementType.Equals(&b.ElementType) { + return false + } + if a.ElementRelationship != b.ElementRelationship { + return false + } + if len(a.Keys) != len(b.Keys) { + return false + } + for i := range a.Keys { + if a.Keys[i] != b.Keys[i] { + return false + } + } + return true +} diff --git a/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go new file mode 100644 index 000000000..6eb6c36df --- /dev/null +++ b/vendor/sigs.k8s.io/structured-merge-diff/v6/schema/schemaschema.go @@ -0,0 +1,165 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package schema + +// SchemaSchemaYAML is a schema against which you can validate other schemas. +// It will validate itself. It can be unmarshalled into a Schema type. +var SchemaSchemaYAML = `types: +- name: schema + map: + fields: + - name: types + type: + list: + elementRelationship: associative + elementType: + namedType: typeDef + keys: + - name +- name: typeDef + map: + fields: + - name: name + type: + scalar: string + - name: scalar + type: + scalar: string + - name: map + type: + namedType: map + - name: list + type: + namedType: list + - name: untyped + type: + namedType: untyped +- name: typeRef + map: + fields: + - name: namedType + type: + scalar: string + - name: scalar + type: + scalar: string + - name: map + type: + namedType: map + - name: list + type: + namedType: list + - name: untyped + type: + namedType: untyped + - name: elementRelationship + type: + scalar: string +- name: scalar + scalar: string +- name: map + map: + fields: + - name: fields + type: + list: + elementType: + namedType: structField + elementRelationship: associative + keys: [ "name" ] + - name: unions + type: + list: + elementType: + namedType: union + elementRelationship: atomic + - name: elementType + type: + namedType: typeRef + - name: elementRelationship + type: + scalar: string +- name: unionField + map: + fields: + - name: fieldName + type: + scalar: string + - name: discriminatorValue + type: + scalar: string +- name: union + map: + fields: + - name: discriminator + type: + scalar: string + - name: deduceInvalidDiscriminator + type: + scalar: boolean + - name: fields + type: + list: + elementRelationship: associative + elementType: + namedType: unionField + keys: + - fieldName +- name: structField + map: + fields: + - name: name + type: + scalar: string + - name: type + type: + namedType: typeRef + - name: default + type: + namedType: __untyped_atomic_ +- name: list + map: + fields: + - name: elementType + type: + namedType: typeRef + - name: elementRelationship + type: + scalar: string + - name: keys + type: + list: + elementType: + scalar: string + elementRelationship: atomic +- name: untyped + map: + fields: + - name: elementRelationship + type: + scalar: string +- name: __untyped_atomic_ + scalar: untyped + list: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic + map: + elementType: + namedType: __untyped_atomic_ + elementRelationship: atomic +`