pax_global_header 0000666 0000000 0000000 00000000064 14610311645 0014513 g ustar 00root root 0000000 0000000 52 comment=fa64d110ed4a77eae5ea2e46ea2d3991e02f0789
nri-0.6.1/ 0000775 0000000 0000000 00000000000 14610311645 0012307 5 ustar 00root root 0000000 0000000 nri-0.6.1/.github/ 0000775 0000000 0000000 00000000000 14610311645 0013647 5 ustar 00root root 0000000 0000000 nri-0.6.1/.github/workflows/ 0000775 0000000 0000000 00000000000 14610311645 0015704 5 ustar 00root root 0000000 0000000 nri-0.6.1/.github/workflows/ci.yml 0000664 0000000 0000000 00000004262 14610311645 0017026 0 ustar 00root root 0000000 0000000 name: CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
checks:
name: Project Checks
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
- uses: actions/setup-go@v4
with:
go-version: 1.20.x
- name: Set env
shell: bash
# TODO(thaJeztah): remove working-directory, path, and GOPATH once project-checks stops needing them; see https://github.com/containerd/nri/pull/53/commits/872fb0ce3dce136f3ae67c068ce78607565194ef#r1324366346
run: |
echo "GOPATH=${{ github.workspace }}" >> $GITHUB_ENV
echo "${{ github.workspace }}/bin" >> $GITHUB_PATH
- uses: actions/checkout@v4
with:
path: src/github.com/containerd/nri
fetch-depth: 25
- uses: containerd/project-checks@v1
with:
working-directory: src/github.com/containerd/nri
test-build:
name: Check buildability
runs-on: ubuntu-22.04
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: 1.20.x
- name: Set env
shell: bash
run: |
echo "${{ github.workspace }}/bin" >> $GITHUB_PATH
- run: |
make all
linters:
name: Linters
runs-on: ${{ matrix.os }}
timeout-minutes: 10
strategy:
matrix:
go: [1.19.x, 1.20.x]
os: [ubuntu-22.04]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
- name: Set env
shell: bash
run: |
echo "${{ github.workspace }}/bin" >> $GITHUB_PATH
- uses: golangci/golangci-lint-action@v3
with:
version: v1.51.2
tests:
name: Tests
runs-on: ubuntu-22.04
timeout-minutes: 5
strategy:
matrix:
go: [1.19.x, 1.20.x]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: ${{ matrix.go }}
- name: Set env
shell: bash
run: |
echo "${{ github.workspace }}/bin" >> $GITHUB_PATH
- run: |
make install-ginkgo test codecov
nri-0.6.1/.github/workflows/codeql.yml 0000664 0000000 0000000 00000001545 14610311645 0017703 0 ustar 00root root 0000000 0000000 name: "CodeQL Scan"
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
contents: read
jobs:
CodeQL-Build:
if: github.repository == 'containerd/nri'
permissions:
actions: read # for github/codeql-action/init to get workflow details
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/analyze to upload SARIF results
strategy:
fail-fast: false
runs-on: ubuntu-22.04
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4
- uses: actions/setup-go@v4
with:
go-version: 1.20.x
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
- run: make
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
nri-0.6.1/.gitignore 0000664 0000000 0000000 00000000007 14610311645 0014274 0 ustar 00root root 0000000 0000000 build/
nri-0.6.1/.golangci.yml 0000664 0000000 0000000 00000002056 14610311645 0014676 0 ustar 00root root 0000000 0000000 linters:
enable:
- staticcheck
- unconvert
- gofmt
- goimports
- ineffassign
- vet
- unused
- misspell
- revive
disable:
- errcheck
issues:
include:
- EXC0002
exclude-rules:
# We have protoc-generated ttRPC/gRPC code. When adding extra functions
# for generated types we want to consistently violate golint's semantic
# function name spelling rules, instead of inconsistently doing so only
# from automatically generated files. These rules are for that.
- path: pkg/adaptation/result.go
linters:
- golint
- revive
text: "should be claim"
# Ignore naming violation in the test suite as well.
- path: pkg/adaptation/adaptation_suite_test.go
linters:
- golint
- revive
text: "should be strip"
# Differ copies pods and containers with Mutexes for diffing. Should be harmless.
- path: plugins/differ/nri-differ.go
linters:
- govet
text: "copylocks: .*protobuf/internal/impl.MessageState.*"
run:
timeout: 2m
nri-0.6.1/LICENSE 0000664 0000000 0000000 00000026135 14610311645 0013323 0 ustar 00root root 0000000 0000000 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.
nri-0.6.1/Makefile 0000664 0000000 0000000 00000010422 14610311645 0013746 0 ustar 00root root 0000000 0000000 # 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.
PROTO_SOURCES = $(shell find . -name '*.proto' | grep -v /vendor/)
PROTO_GOFILES = $(patsubst %.proto,%.pb.go,$(PROTO_SOURCES))
PROTO_INCLUDE = -I$(PWD):/usr/local/include:/usr/include
PROTO_OPTIONS = --proto_path=. $(PROTO_INCLUDE) \
--go_opt=paths=source_relative --go_out=. \
--go-ttrpc_opt=paths=source_relative --go-ttrpc_out=.
PROTO_COMPILE = PATH=$(PATH):$(shell go env GOPATH)/bin; protoc $(PROTO_OPTIONS)
GO_CMD := go
GO_BUILD := $(GO_CMD) build
GO_INSTALL := $(GO_CMD) install
GO_TEST := $(GO_CMD) test
GO_LINT := golint -set_exit_status
GO_FMT := gofmt
GO_VET := $(GO_CMD) vet
GO_MODULES := $(shell $(GO_CMD) list ./...)
GOLANG_CILINT := golangci-lint
GINKGO := ginkgo
BUILD_PATH := $(shell pwd)/build
BIN_PATH := $(BUILD_PATH)/bin
COVERAGE_PATH := $(BUILD_PATH)/coverage
PLUGINS := \
$(BIN_PATH)/logger \
$(BIN_PATH)/device-injector \
$(BIN_PATH)/hook-injector \
$(BIN_PATH)/differ \
$(BIN_PATH)/ulimit-adjuster \
$(BIN_PATH)/v010-adapter \
$(BIN_PATH)/template
ifneq ($(V),1)
Q := @
endif
#
# top-level targets
#
all: build build-plugins
build: build-proto build-check
clean: clean-plugins
allclean: clean clean-cache
test: test-gopkgs
#
# build targets
#
build-proto: $(PROTO_GOFILES)
build-plugins: $(PLUGINS)
build-check:
$(Q)$(GO_BUILD) -v $(GO_MODULES)
#
# clean targets
#
clean-plugins:
$(Q)rm -f $(PLUGINS)
clean-cache:
$(Q)$(GO_CMD) clean -cache -testcache
#
# plugins build targets
#
$(BIN_PATH)/logger: $(wildcard plugins/logger/*.go)
$(Q)echo "Building $@..."; \
cd $(dir $<) && $(GO_BUILD) -o $@ .
$(BIN_PATH)/device-injector: $(wildcard plugins/device-injector/*.go)
$(Q)echo "Building $@..."; \
cd $(dir $<) && $(GO_BUILD) -o $@ .
$(BIN_PATH)/hook-injector: $(wildcard plugins/hook-injector/*.go)
$(Q)echo "Building $@..."; \
cd $(dir $<) && $(GO_BUILD) -o $@ .
$(BIN_PATH)/differ: $(wildcard plugins/differ/*.go)
$(Q)echo "Building $@..."; \
cd $(dir $<) && $(GO_BUILD) -o $@ .
$(BIN_PATH)/ulimit-adjuster: $(wildcard plugins/ulimit-adjuster/*.go)
$(Q)echo "Building $@..."; \
cd $(dir $<) && $(GO_BUILD) -o $@ .
$(BIN_PATH)/v010-adapter: $(wildcard plugins/v010-adapter/*.go)
$(Q)echo "Building $@..."; \
cd $(dir $<) && $(GO_BUILD) -o $@ .
$(BIN_PATH)/template: $(wildcard plugins/template/*.go)
$(Q)echo "Building $@..."; \
cd $(dir $<) && $(GO_BUILD) -o $@ .
#
# test targets
#
test-gopkgs: ginkgo-tests test-ulimits
SKIPPED_PKGS="ulimit-adjuster"
ginkgo-tests:
$(Q)$(GINKGO) run \
--race \
--trace \
--cover \
--covermode atomic \
--output-dir $(COVERAGE_PATH) \
--junit-report junit.xml \
--coverprofile coverprofile \
--succinct \
--skip-package $(SKIPPED_PKGS) \
-r .; \
$(GO_CMD) tool cover -html=$(COVERAGE_PATH)/coverprofile -o $(COVERAGE_PATH)/coverage.html
test-ulimits:
$(Q)cd ./plugins/ulimit-adjuster && $(GO_TEST) -v
codecov: SHELL := $(shell which bash)
codecov:
bash <(curl -s https://codecov.io/bash) -f $(COVERAGE_PATH)/coverprofile
#
# other validation targets
#
fmt format:
$(Q)$(GO_FMT) -s -d -e .
lint:
$(Q)$(GO_LINT) -set_exit_status ./...
vet:
$(Q)$(GO_VET) ./...
golangci-lint:
$(Q)$(GOLANG_CILINT) run
#
# proto generation targets
#
%.pb.go: %.proto
$(Q)echo "Generating $@..."; \
$(PROTO_COMPILE) $<
#
# targets for installing dependencies
#
install-protoc install-protobuf:
$(Q)./scripts/install-protobuf
install-ttrpc-plugin:
$(Q)$(GO_INSTALL) -mod=mod github.com/containerd/ttrpc/cmd/protoc-gen-go-ttrpc@74421d10189e8c118870d294c9f7f62db2d33ec1
install-protoc-dependencies:
$(Q)$(GO_INSTALL) -mod=mod google.golang.org/protobuf/cmd/protoc-gen-go@v1.28.0
install-ginkgo:
$(Q)$(GO_INSTALL) -mod=mod github.com/onsi/ginkgo/v2/ginkgo
nri-0.6.1/README-v0.1.0.md 0000664 0000000 0000000 00000006250 14610311645 0014411 0 ustar 00root root 0000000 0000000 # nri - Node Resource Interface
*This version of NRI is supported through the included v010-adapter plugin.*
This project is a WIP for a new, CNI like, interface for managing resources on a node for Pods and Containers.
## Documentation
The basic interface, concepts and plugin design of the Container Network Interface (CNI) is an elegant way to handle multiple implementations of the network stack for containers.
This concept can be used for additional interfaces to customize a container's runtime environment.
This proposal covers a new interface for resource management on a node with a structured API and plugin design for containers.
## Lifecycle
The big selling point for CNI is that it has a structured interface for modifying the network namespace for a container.
This is different from generic hooks as they lack a type safe API injected into the lifecycle of a container.
The lifecycle point that CNI and NRI plugins will be injected into is the point between `Create` and `Start` of the container's init process.
`Create->NRI->Start`
## Configuration
Configuration is split into two parts. One is the payload that is specific to a plugin invocation while the second is the host level configuration and options that specify what plugins to run and provide additional configuration to a plugin.
### Filepath and Binaries
Plugin binary paths can be configured via the consumer but will default to `/opt/nri/bin`.
Binaries are named with their type as the binary name, same as the CNI plugin naming scheme.
### Host Level Config
The config's default location will be `/etc/nri/resource.d/*.conf`.
```json
{
"version": "0.1",
"plugins": [
{
"type": "konfine",
"conf": {
"systemReserved": [0, 1]
}
},
{
"type": "clearcfs"
}
]
}
```
### Input
Input to a plugin is provided via `STDIN` as a `json` payload.
```json
{
"version": "0.1",
"state": "create",
"id": "redis",
"pid": 1234,
"spec": {
"resources": {},
"cgroupsPath": "default/redis",
"namespaces": {
"pid": "/proc/44/ns/pid",
"mount": "/proc/44/ns/mnt",
"net": "/proc/44/ns/net"
},
"annotations": {
"qos.class": "ls"
}
}
}
```
### Output
```json
{
"version": "0.1",
"state": "create",
"id": "redis",
"pid": 1234,
"cgroupsPath": "qos-ls/default/redis"
}
```
## Commands
* Invoke - provides invocations into different lifecycle changes of a container
- states: `setup|pause|resume|update|delete`
## Packages
A Go based API and client package will be created for both producers of plugins and consumers, commonly being the container runtime (containerd).
### Sample Plugin
* [clearcfs](examples/clearcfs/main.go)
## Project details
nri 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.
nri-0.6.1/README.md 0000664 0000000 0000000 00000034133 14610311645 0013572 0 ustar 00root root 0000000 0000000 # Node Resource Interface, Revisited
[](https://pkg.go.dev/github.com/containerd/nri)
[](https://github.com/containerd/nri/actions?query=workflow%3ACI)
[](https://codecov.io/gh/containerd/nri)
[](https://goreportcard.com/report/github.com/containerd/nri)
*This project is currently in DRAFT status*
## Goal
NRI allows plugging domain- or vendor-specific custom logic into OCI-
compatible runtimes. This logic can make controlled changes to containers
or perform extra actions outside the scope of OCI at certain points in a
containers lifecycle. This can be used, for instance, for improved allocation
and management of devices and other container resources.
NRI defines the interfaces and implements the common infrastructure for
enabling such pluggable runtime extensions, NRI plugins. This also keeps
the plugins themselves runtime-agnostic.
The goal is to enable NRI support in the most commonly used OCI runtimes,
[containerd](https://github.com/containerd/containerd) and
[CRI-O](https://github.com/cri-o/cri-o).
## Background
The revisited API is a major rewrite of NRI. It changes the scope of NRI
and how it gets integrated into runtimes. It reworks how plugins are
implemented, how they communicate with the runtime, and what kind of
changes they can make to containers.
[NRI v0.1.0](README-v0.1.0.md) used an OCI hook-like one-shot plugin invocation
mechanism where a separate instance of a plugin was spawned for every NRI
event. This instance then used its standard input and output to receive a
request and provide a response, both as JSON data.
Plugins in NRI are daemon-like entities. A single instance of a plugin is
now responsible for handling the full stream of NRI events and requests. A
unix-domain socket is used as the transport for communication. Instead of
JSON requests and responses NRI is defined as a formal, protobuf-based
'NRI plugin protocol' which is compiled into ttRPC bindings. This should
result in improved communication efficiency with lower per-message overhead,
and enable straightforward implementation of stateful NRI plugins.
## Components
The NRI implementation consists of a number of components. The core of
these are essential for implementing working end-to-end NRI support in
runtimes. These core components are the actual [NRI protocol](pkg/api),
and the [NRI runtime adaptation](pkg/adaptation).
Together these establish the model of how a runtime interacts with NRI and
how plugins interact with containers in the runtime through NRI. They also
define under which conditions plugins can make changes to containers and
the extent of these changes.
The rest of the components are the [NRI plugin stub library](pkg/stub)
and [some sample NRI plugins](plugins). [Some plugins](plugins/hook-injector)
implement useful functionality in real world scenarios. [A few](plugins/differ)
[others](plugins/logger) are useful for debugging. All of the sample plugins
serve as practical examples of how the stub library can be used to implement
NRI plugins.
## Protocol, Plugin API
The core of NRI is defined by a protobuf [protocol definition](pkg/api/api.proto)
of the low-level plugin API. The API defines two services, Runtime and Plugin.
The Runtime service is the public interface runtimes expose for NRI plugins. All
requests on this interface are initiated by the plugin. The interface provides
functions for
- initiating plugin registration
- requesting unsolicited updates to containers
The Plugin service is the public interface NRI uses to interact with plugins.
All requests on this interface are initiated by NRI/the runtime. The interface
provides functions for
- configuring the plugin
- getting initial list of already existing pods and containers
- hooking the plugin into pod/container lifecycle events
- shutting down the plugin
### Plugin Registration
Before a plugin can start receiving and processing container events, it needs
to register itself with NRI. During registration the plugin and NRI perform a
handshake sequence which consists of the following steps:
1. the plugin identifies itself to the runtime
2. NRI provides plugin-specific configuration data to the plugin
3. the plugin subscribes to pod and container lifecycle events of interest
4. NRI sends list of existing pods and containers to plugin
5. the plugin requests any updates deemed necessary to existing containers
The plugin identifies itself to NRI by a plugin name and a plugin index. The
plugin index is used by NRI to determine in which order the plugin is hooked
into pod and container lifecycle event processing with respect to any other
plugins.
The plugin name is used to pick plugin-specific data to send to the plugin
as configuration. This data is only present if the plugin has been launched
by NRI. If the plugin has been externally started it is expected to acquire
its configuration also by external means. The plugin subscribes to pod and
container lifecycle events of interest in its response to configuration.
As the last step in the registration and handshaking process, NRI sends the
full set of pods and containers known to the runtime. The plugin can request
updates it considers necessary to any of the known containers in response.
Once the handshake sequence is over and the plugin has registered with NRI,
it will start receiving pod and container lifecycle events according to its
subscription.
### Pod Data and Available Lifecycle Events
NRI Pod Lifecycle Events
NRI plugins can subscribe to the following pod lifecycle events:
- creation
- stopping
- removal
The following pieces of pod metadata are available to plugins in NRI:
- ID
- name
- UID
- namespace
- labels
- annotations
- cgroup parent directory
- runtime handler name
### Container Data and Available Lifecycle Events
NRI Container Lifecycle Events
NRI plugins can subscribe to the following container lifecycle events:
- creation (*)
- post-creation
- starting
- post-start
- updating (*)
- post-update
- stopping (*)
- removal
*) Plugins can request adjustment or updates to containers in response to
these events.
The following pieces of container metadata are available to plugins in NRI:
- ID
- pod ID
- name
- state
- labels
- annotations
- command line arguments
- environment variables
- mounts
- OCI hooks
- rlimits
- linux
- namespace IDs
- devices
- resources
- memory
- limit
- reservation
- swap limit
- kernel limit
- kernel TCP limit
- swappiness
- OOM disabled flag
- hierarchical accounting flag
- hugepage limits
- CPU
- shares
- quota
- period
- realtime runtime
- realtime period
- cpuset CPUs
- cpuset memory
- Block I/O class
- RDT class
Apart from data identifying the container, these pieces of information
represent the corresponding data in the container's OCI Spec.
### Container Adjustment
During container creation plugins can request changes to the following
container parameters:
- annotations
- mounts
- environment variables
- OCI hooks
- rlimits
- linux
- devices
- resources
- memory
- limit
- reservation
- swap limit
- kernel limit
- kernel TCP limit
- swappiness
- OOM disabled flag
- hierarchical accounting flag
- hugepage limits
- CPU
- shares
- quota
- period
- realtime runtime
- realtime period
- cpuset CPUs
- cpuset memory
- Block I/O class
- RDT class
### Container Updates
Once a container has been created plugins can request updates to them.
These updates can be requested in response to another containers creation
request, in response to any containers update request, in response to any
containers stop request, or they can be requested as part of a separate
unsolicited container update request. The following container parameters
can be updated this way:
- resources
- memory
- limit
- reservation
- swap limit
- kernel limit
- kernel TCP limit
- swappiness
- OOM disabled flag
- hierarchical accounting flag
- hugepage limits
- CPU
- shares
- quota
- period
- realtime runtime
- realtime period
- cpuset CPUs
- cpuset memory
- Block I/O class
- RDT class
## Runtime Adaptation
The NRI [runtime adaptation](pkg/adaptation) package is the interface
runtimes use to integrate to NRI and interact with NRI plugins. It
implements basic plugin discovery, startup and configuration. It also
provides the functions necessary to hook NRI plugins into lifecycle
events of pods and containers from the runtime.
The package hides the fact that multiple NRI plugins might be processing
any single pod or container lifecycle event. It takes care of invoking
plugins in the correct order and combining responses by multiple plugins
into a single one. While combining responses, the package detects any
unintentional conflicting changes made by multiple plugins to a single
container and flags such an event as an error to the runtime.
## Wrapped OCI Spec Generator
The [OCI Spec generator](pkg/runtime-tools/generate) package wraps the
[corresponding package](https://github.com/opencontainers/runtime-tools/tree/master/generate)
and adds functions for applying NRI container adjustments and updates to
OCI Specs. This package can be used by runtime NRI integration code to
apply NRI responses to containers.
## Plugin Stub Library
The plugin stub hides many of the low-level details of implementing an NRI
plugin. It takes care of connection establishment, plugin registration,
configuration, and event subscription. All [sample plugins](pkg/plugins)
are implemented using the stub. Any of these can be used as a tutorial on
how the stub library should be used.
## Sample Plugins
The following sample plugins exist for NRI:
- [logger](plugins/logger)
- [differ](plugins/differ)
- [device injector](plugins/device-injector)
- [OCI hook injector](plugins/hook-injector)
- [ulimit adjuster](plugins/ulimit-adjuster)
- [NRI v0.1.0 plugin adapter](plugins/v010-adapter)
Please see the documentation of these plugins for further details
about what and how each of these plugins can be used for.
## Security Considerations
From a security perspective NRI plugins should be considered part of the
container runtime. NRI does not implement granular access control to the
functionality it offers. Access to NRI is controlled by restricting access
to the systemwide NRI socket. If a process can connect to the NRI socket
and send data, it has access to the full scope of functionality available
via NRI.
In particular this includes
- injection of OCI hooks, which allow for arbitrary execution of processes with the same privilege level as the container runtime
- arbitrary changes to mounts, including new bind-mounts, changes to the proc, sys, mqueue, shm, and tmpfs mounts
- the addition or removal of arbitrary devices
- arbitrary changes to the limits for memory, CPU, block I/O, and RDT resources available, including the ability to deny service by setting limits very low
The same precautions and principles apply to protecting the NRI socket as
to protecting the socket of the runtime itself. Unless it already exists,
NRI itself creates the directory to hold its socket with permissions that
allow access only for the user ID of the runtime process. By default this
limits NRI access to processes running as root (UID 0). Changing the default
socket permissions is strongly advised against. Enabling more permissive
access control to NRI should never be done without fully understanding the
full implications and potential consequences to container security.
### Plugins as Kubernetes DaemonSets
When the runtime manages pods and containers in a Kubernetes cluster, it
is convenient to deploy and manage NRI plugins using Kubernetes DaemonSets.
Among other things, this requires bind-mounting the NRI socket into the
filesystem of a privileged container running the plugin. Similar precautions
apply and the same care should be taken for protecting the NRI socket and
NRI plugins as for the kubelet DeviceManager socket and Kubernetes Device
Plugins.
The cluster configuration should make sure that unauthorized users cannot
bind-mount host directories and create privileged containers which gain
access to these sockets and can act as NRI or Device Plugins. See the
[related documentation](https://kubernetes.io/docs/concepts/security/)
and [best practices](https://kubernetes.io/docs/setup/best-practices/enforcing-pod-security-standards/)
about Kubernetes security.
## API Stability
NRI APIs should not be considered stable yet. We try to avoid unnecessarily
breaking APIs, especially the Stub API which plugins use to interact with NRI.
However, before NRI reaches a stable 1.0.0 release, this is only best effort
and cannot be guaranteed. Meanwhile we do our best to document any API breaking
changes for each release in the [release notes](RELEASES.md).
The current target for a stable v1 API through a 1.0.0 release is the end of
this year.
## Project details
nri 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.
nri-0.6.1/RELEASES.md 0000664 0000000 0000000 00000003023 14610311645 0014032 0 ustar 00root root 0000000 0000000 # Release Notes
## 0.4.0
- Pass the ttRPC receiving context from the Stub to each NRI request handler
of the plugin.
- Fix Stub/Plugin UpdateContainer interface to pass the resource update to
the UpdateContainer NRI request handler of the plugin as the last argument.
- All plugins need to be updated to reflect the above changes in any NRI
request handler they implement.
- NRI plugins can now add rlimits
## 0.3.0
- Eliminate the global NRI configuration file, replacing any remaining
configuration options with corresponding programmatic options for runtimes.
- Change default socket path from /var/run/nri.sock to /var/run/nri/nri.sock.
- Make plugin timeouts configurable on the runtime side.
- Plugins should be API-compatible between 0.2.0 and 0.3.0, but either the
runtime needs to be configured to use the old NRI socket path, or 0.2.0 plugins
need to be configured to use the new default NRI socket path.
## 0.2.0
- Replace the v0.1.0 CNI like plugin interface with JSON message exchange on
stdin and stdout with external daemon-like plugins and a protobuf-defined
protocol with ttRPC bindings for communicating with the runtime.
- Allow plugins to track the state of (CRI) pods and containers.
- Allow plugins to make changes to a selected subset of container parameters
during container creation, update, and stopping of (other) containers.
- All 0.1.0 plugins are incompatible with 0.2.0, although
[an experimental adapter plugin](plugins/v010-adapter) is provided to bridge
between any existing 0.1.0 plugins and the current NRI APIs.
nri-0.6.1/client.go 0000664 0000000 0000000 00000011574 14610311645 0014124 0 ustar 00root root 0000000 0000000 /*
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 nri
import (
"bytes"
"context"
"encoding/json"
"fmt"
"os"
"os/exec"
"sync"
types "github.com/containerd/nri/types/v1"
oci "github.com/opencontainers/runtime-spec/specs-go"
)
const (
// DefaultBinaryPath for nri plugins
DefaultBinaryPath = "/opt/nri/bin"
// DefaultConfPath for the global nri configuration
DefaultConfPath = "/etc/nri/conf.json"
// Version of NRI
Version = "0.1"
)
var appendPathOnce sync.Once
// New nri client
func New() (*Client, error) {
conf, err := loadConfig(DefaultConfPath)
if err != nil {
return nil, err
}
appendPathOnce.Do(func() {
err = os.Setenv("PATH", fmt.Sprintf("%s:%s", os.Getenv("PATH"), DefaultBinaryPath))
})
if err != nil {
return nil, err
}
return &Client{
conf: conf,
}, nil
}
// Client for calling nri plugins
type Client struct {
conf *types.ConfigList
}
// Sandbox information
type Sandbox struct {
// ID of the sandbox
ID string
// Labels of the sandbox
Labels map[string]string
}
// process is a subset of containerd's Process interface.
type process interface {
// ID of the process
ID() string
// Pid is the system specific process id
Pid() uint32
}
// Task is a subset of containerd's Task interface.
type Task interface {
process
// Spec returns the current OCI specification for the task
Spec(context.Context) (*oci.Spec, error)
}
// Invoke the ConfList of nri plugins
func (c *Client) Invoke(ctx context.Context, task Task, state types.State) ([]*types.Result, error) {
return c.InvokeWithSandbox(ctx, task, state, nil)
}
// InvokeWithSandbox invokes the ConfList of nri plugins
func (c *Client) InvokeWithSandbox(ctx context.Context, task Task, state types.State, sandbox *Sandbox) ([]*types.Result, error) {
if len(c.conf.Plugins) == 0 {
return nil, nil
}
spec, err := task.Spec(ctx)
if err != nil {
return nil, err
}
rs, err := createSpec(spec)
if err != nil {
return nil, err
}
r := &types.Request{
Version: c.conf.Version,
ID: task.ID(),
Pid: int(task.Pid()),
State: state,
Spec: rs,
}
if sandbox != nil {
r.SandboxID = sandbox.ID
r.Labels = sandbox.Labels
}
for _, p := range c.conf.Plugins {
r.Conf = p.Conf
result, err := c.invokePlugin(ctx, p.Type, r)
if err != nil {
return nil, fmt.Errorf("plugin: %s: %w", p.Type, err)
}
r.Results = append(r.Results, result)
}
return r.Results, nil
}
func (c *Client) invokePlugin(ctx context.Context, name string, r *types.Request) (*types.Result, error) {
payload, err := json.Marshal(r)
if err != nil {
return nil, err
}
cmd := exec.CommandContext(ctx, name, "invoke")
cmd.Stdin = bytes.NewBuffer(payload)
cmd.Stderr = os.Stderr
out, err := cmd.Output()
msg := "output:"
if len(out) > 0 {
msg = fmt.Sprintf("%s %q", msg, out)
} else {
msg = fmt.Sprintf("%s ", msg)
}
if err != nil {
if exitErr, ok := err.(*exec.ExitError); ok {
// ExitError is returned when there is a non-zero exit status
msg = fmt.Sprintf("%s exit code: %d", msg, exitErr.ExitCode())
} else {
// plugin did not get a chance to run, return exec err
return nil, err
}
}
var result types.Result
if err := json.Unmarshal(out, &result); err != nil {
return nil, fmt.Errorf("failed to unmarshal plugin output %s: %w", msg, err)
}
if result.Err() != nil {
return nil, result.Err()
}
return &result, nil
}
func loadConfig(path string) (*types.ConfigList, error) {
f, err := os.Open(path)
if err != nil {
// if we don't have a config list on disk, create a new one for use
if os.IsNotExist(err) {
return &types.ConfigList{
Version: Version,
}, nil
}
return nil, err
}
var c types.ConfigList
err = json.NewDecoder(f).Decode(&c)
f.Close()
if err != nil {
return nil, err
}
return &c, nil
}
func createSpec(spec *oci.Spec) (*types.Spec, error) {
s := types.Spec{
Namespaces: make(map[string]string),
Annotations: spec.Annotations,
}
switch {
case spec.Linux != nil:
s.CgroupsPath = spec.Linux.CgroupsPath
data, err := json.Marshal(spec.Linux.Resources)
if err != nil {
return nil, err
}
s.Resources = json.RawMessage(data)
for _, ns := range spec.Linux.Namespaces {
s.Namespaces[string(ns.Type)] = ns.Path
}
case spec.Windows != nil:
data, err := json.Marshal(spec.Windows.Resources)
if err != nil {
return nil, err
}
s.Resources = json.RawMessage(data)
}
return &s, nil
}
nri-0.6.1/docs/ 0000775 0000000 0000000 00000000000 14610311645 0013237 5 ustar 00root root 0000000 0000000 nri-0.6.1/docs/nri-container-lifecycle.svg 0000664 0000000 0000000 00001367410 14610311645 0020501 0 ustar 00root root 0000000 0000000
nri-0.6.1/docs/nri-pod-lifecycle.svg 0000664 0000000 0000000 00000573350 14610311645 0017302 0 ustar 00root root 0000000 0000000
nri-0.6.1/examples/ 0000775 0000000 0000000 00000000000 14610311645 0014125 5 ustar 00root root 0000000 0000000 nri-0.6.1/examples/clearcfs/ 0000775 0000000 0000000 00000000000 14610311645 0015707 5 ustar 00root root 0000000 0000000 nri-0.6.1/examples/clearcfs/main.go 0000664 0000000 0000000 00000003224 14610311645 0017163 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"fmt"
"os"
"github.com/containerd/cgroups"
"github.com/containerd/nri/skel"
types "github.com/containerd/nri/types/v1"
"github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
)
// clearCFS clears any cfs quotas for the containers
type clearCFS struct {
}
func (c *clearCFS) Type() string {
return "clearcfs"
}
func (c *clearCFS) Invoke(ctx context.Context, r *types.Request) (*types.Result, error) {
result := r.NewResult(c.Type())
if r.State != types.Create {
return result, nil
}
switch r.Spec.Annotations["qos.class"] {
case "ls":
logrus.Debugf("clearing cfs for %s", r.ID)
control, err := cgroups.Load(cgroups.V1, cgroups.StaticPath(r.Spec.CgroupsPath))
if err != nil {
return nil, err
}
quota := int64(-1)
return result, control.Update(&specs.LinuxResources{
CPU: &specs.LinuxCPU{
Quota: "a,
},
})
}
return result, nil
}
func main() {
ctx := context.Background()
if err := skel.Run(ctx, &clearCFS{}); err != nil {
fmt.Fprintf(os.Stderr, "%s", err)
os.Exit(1)
}
}
nri-0.6.1/examples/go.mod 0000664 0000000 0000000 00000001025 14610311645 0015231 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/examples
go 1.18
require (
github.com/containerd/cgroups v1.0.3
github.com/containerd/nri v0.1.0
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
github.com/sirupsen/logrus v1.8.1
)
require (
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/godbus/dbus/v5 v5.0.4 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
golang.org/x/sys v0.13.0 // indirect
)
replace github.com/containerd/nri => ../
nri-0.6.1/examples/go.sum 0000664 0000000 0000000 00000020414 14610311645 0015261 0 ustar 00root root 0000000 0000000 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4=
github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8=
github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
nri-0.6.1/go.mod 0000664 0000000 0000000 00000002413 14610311645 0013415 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri
go 1.19
require (
github.com/containerd/ttrpc v1.2.3
github.com/moby/sys/mountinfo v0.6.2
github.com/onsi/ginkgo/v2 v2.5.0
github.com/onsi/gomega v1.24.0
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
github.com/opencontainers/runtime-tools v0.9.0
github.com/sirupsen/logrus v1.8.1
github.com/stretchr/testify v1.8.0
golang.org/x/sys v0.13.0
google.golang.org/protobuf v1.31.0
k8s.io/cri-api v0.25.3
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-logr/logr v1.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
replace github.com/opencontainers/runtime-tools v0.9.0 => github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809
nri-0.6.1/go.sum 0000664 0000000 0000000 00000025315 14610311645 0013450 0 ustar 00root root 0000000 0000000 github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM=
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/mndrix/tap-go v0.0.0-20171203230836-629fa407e90b/go.mod h1:pzzDgJWZ34fGzaAZGFW22KVZDfyrYW+QABMrWnJBnSs=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls=
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809 h1:WSwkWIIS4s+E/dPF6HuVZ/hnq1WfXN371eESjREnU8k=
github.com/opencontainers/runtime-tools v0.0.0-20221026201742-946c877fa809/go.mod h1:BRHJJd0E+cx42OybVYSgUvZmU0B8P9gZuRXlZUP7TKI=
github.com/opencontainers/selinux v1.9.1 h1:b4VPEF3O5JLZgdTDBmGepaaIbAo0GqoF6EBRq5f/g3Y=
github.com/opencontainers/selinux v1.9.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/urfave/cli v1.19.1/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/pkg/ 0000775 0000000 0000000 00000000000 14610311645 0013070 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/adaptation/ 0000775 0000000 0000000 00000000000 14610311645 0015214 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/adaptation/adaptation.go 0000664 0000000 0000000 00000030763 14610311645 0017700 0 ustar 00root root 0000000 0000000 /*
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 adaptation
import (
"context"
"errors"
"fmt"
"io/fs"
"net"
"os"
"path/filepath"
"sort"
"sync"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/log"
"github.com/containerd/ttrpc"
)
const (
// DefaultPluginPath is the default path to search for NRI plugins.
DefaultPluginPath = "/opt/nri/plugins"
// DefaultSocketPath is the default socket path for external plugins.
DefaultSocketPath = api.DefaultSocketPath
// PluginConfigDir is the drop-in directory for NRI-launched plugin configuration.
DefaultPluginConfigPath = "/etc/nri/conf.d"
)
// SyncFn is a container runtime function for state synchronization.
type SyncFn func(context.Context, SyncCB) error
// SyncCB is an NRI function used to synchronize plugins with the runtime.
type SyncCB func(context.Context, []*PodSandbox, []*Container) ([]*ContainerUpdate, error)
// UpdateFn is a container runtime function for unsolicited container updates.
type UpdateFn func(context.Context, []*ContainerUpdate) ([]*ContainerUpdate, error)
// Adaptation is the NRI abstraction for container runtime NRI adaptation/integration.
type Adaptation struct {
sync.Mutex
name string
version string
dropinPath string
pluginPath string
socketPath string
dontListen bool
syncFn SyncFn
updateFn UpdateFn
clientOpts []ttrpc.ClientOpts
serverOpts []ttrpc.ServerOpt
listener net.Listener
plugins []*plugin
}
var (
// Used instead of nil Context in logging.
noCtx = context.TODO()
)
// Option to apply to the NRI runtime.
type Option func(*Adaptation) error
// WithPluginPath returns an option to override the default NRI plugin path.
func WithPluginPath(path string) Option {
return func(r *Adaptation) error {
r.pluginPath = path
return nil
}
}
// WithPluginConfigPath returns an option to override the default NRI plugin config path.
func WithPluginConfigPath(path string) Option {
return func(r *Adaptation) error {
r.dropinPath = path
return nil
}
}
// WithSocketPath returns an option to override the default NRI socket path.
func WithSocketPath(path string) Option {
return func(r *Adaptation) error {
r.socketPath = path
return nil
}
}
// WithDisabledExternalConnections returns an options to disable accepting plugin connections.
func WithDisabledExternalConnections() Option {
return func(r *Adaptation) error {
r.dontListen = true
return nil
}
}
// WithTTRPCOptions sets extra client and server options to use for ttrpc.
func WithTTRPCOptions(clientOpts []ttrpc.ClientOpts, serverOpts []ttrpc.ServerOpt) Option {
return func(r *Adaptation) error {
r.clientOpts = append(r.clientOpts, clientOpts...)
r.serverOpts = append(r.serverOpts, serverOpts...)
return nil
}
}
// New creates a new NRI Runtime.
func New(name, version string, syncFn SyncFn, updateFn UpdateFn, opts ...Option) (*Adaptation, error) {
var err error
if syncFn == nil {
return nil, fmt.Errorf("failed to create NRI adaptation, nil SyncFn")
}
if updateFn == nil {
return nil, fmt.Errorf("failed to create NRI adaptation, nil UpdateFn")
}
r := &Adaptation{
name: name,
version: version,
syncFn: syncFn,
updateFn: updateFn,
pluginPath: DefaultPluginPath,
dropinPath: DefaultPluginConfigPath,
socketPath: DefaultSocketPath,
}
for _, o := range opts {
if err = o(r); err != nil {
return nil, fmt.Errorf("failed to apply option: %w", err)
}
}
log.Infof(noCtx, "runtime interface created")
return r, nil
}
// Start up the NRI runtime.
func (r *Adaptation) Start() error {
log.Infof(noCtx, "runtime interface starting up...")
r.Lock()
defer r.Unlock()
if err := r.startPlugins(); err != nil {
return err
}
if err := r.startListener(); err != nil {
return err
}
return nil
}
// Stop the NRI runtime.
func (r *Adaptation) Stop() {
log.Infof(noCtx, "runtime interface shutting down...")
r.Lock()
defer r.Unlock()
r.stopListener()
r.stopPlugins()
}
// RunPodSandbox relays the corresponding CRI event to plugins.
func (r *Adaptation) RunPodSandbox(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_RUN_POD_SANDBOX
return r.StateChange(ctx, evt)
}
// StopPodSandbox relays the corresponding CRI event to plugins.
func (r *Adaptation) StopPodSandbox(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_STOP_POD_SANDBOX
return r.StateChange(ctx, evt)
}
// RemovePodSandbox relays the corresponding CRI event to plugins.
func (r *Adaptation) RemovePodSandbox(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_REMOVE_POD_SANDBOX
return r.StateChange(ctx, evt)
}
// CreateContainer relays the corresponding CRI request to plugins.
func (r *Adaptation) CreateContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) {
r.Lock()
defer r.Unlock()
defer r.removeClosedPlugins()
result := collectCreateContainerResult(req)
for _, plugin := range r.plugins {
rpl, err := plugin.createContainer(ctx, req)
if err != nil {
return nil, err
}
err = result.apply(rpl, plugin.name())
if err != nil {
return nil, err
}
}
return result.createContainerResponse(), nil
}
// PostCreateContainer relays the corresponding CRI event to plugins.
func (r *Adaptation) PostCreateContainer(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_POST_CREATE_CONTAINER
return r.StateChange(ctx, evt)
}
// StartContainer relays the corresponding CRI event to plugins.
func (r *Adaptation) StartContainer(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_START_CONTAINER
return r.StateChange(ctx, evt)
}
// PostStartContainer relays the corresponding CRI event to plugins.
func (r *Adaptation) PostStartContainer(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_POST_START_CONTAINER
return r.StateChange(ctx, evt)
}
// UpdateContainer relays the corresponding CRI request to plugins.
func (r *Adaptation) UpdateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) {
r.Lock()
defer r.Unlock()
defer r.removeClosedPlugins()
result := collectUpdateContainerResult(req)
for _, plugin := range r.plugins {
rpl, err := plugin.updateContainer(ctx, req)
if err != nil {
return nil, err
}
err = result.apply(rpl, plugin.name())
if err != nil {
return nil, err
}
}
return result.updateContainerResponse(), nil
}
// PostUpdateContainer relays the corresponding CRI event to plugins.
func (r *Adaptation) PostUpdateContainer(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_POST_UPDATE_CONTAINER
return r.StateChange(ctx, evt)
}
// StopContainer relays the corresponding CRI request to plugins.
func (r *Adaptation) StopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) {
r.Lock()
defer r.Unlock()
defer r.removeClosedPlugins()
result := collectStopContainerResult()
for _, plugin := range r.plugins {
rpl, err := plugin.stopContainer(ctx, req)
if err != nil {
return nil, err
}
err = result.apply(rpl, plugin.name())
if err != nil {
return nil, err
}
}
return result.stopContainerResponse(), nil
}
// RemoveContainer relays the corresponding CRI event to plugins.
func (r *Adaptation) RemoveContainer(ctx context.Context, evt *StateChangeEvent) error {
evt.Event = Event_REMOVE_CONTAINER
return r.StateChange(ctx, evt)
}
// StateChange relays pod- or container events to plugins.
func (r *Adaptation) StateChange(ctx context.Context, evt *StateChangeEvent) error {
if evt.Event == Event_UNKNOWN {
return errors.New("invalid (unset) event in state change notification")
}
r.Lock()
defer r.Unlock()
defer r.removeClosedPlugins()
for _, plugin := range r.plugins {
err := plugin.StateChange(ctx, evt)
if err != nil {
return err
}
}
return nil
}
// Perform a set of unsolicited container updates requested by a plugin.
func (r *Adaptation) updateContainers(ctx context.Context, req []*ContainerUpdate) ([]*ContainerUpdate, error) {
r.Lock()
defer r.Unlock()
return r.updateFn(ctx, req)
}
// Start up pre-installed plugins.
func (r *Adaptation) startPlugins() (retErr error) {
var plugins []*plugin
log.Infof(noCtx, "starting plugins...")
ids, names, configs, err := r.discoverPlugins()
if err != nil {
return err
}
defer func() {
if retErr != nil {
for _, p := range plugins {
p.stop()
}
}
}()
for i, name := range names {
log.Infof(noCtx, "starting plugin %q...", name)
id := ids[i]
p, err := r.newLaunchedPlugin(r.pluginPath, id, name, configs[i])
if err != nil {
return fmt.Errorf("failed to start NRI plugin %q: %w", name, err)
}
if err := p.start(r.name, r.version); err != nil {
return err
}
plugins = append(plugins, p)
}
r.plugins = plugins
r.sortPlugins()
return nil
}
// Stop plugins.
func (r *Adaptation) stopPlugins() {
log.Infof(noCtx, "stopping plugins...")
for _, p := range r.plugins {
p.stop()
}
r.plugins = nil
}
func (r *Adaptation) removeClosedPlugins() {
active := []*plugin{}
for _, p := range r.plugins {
if !p.isClosed() {
active = append(active, p)
}
}
r.plugins = active
}
func (r *Adaptation) startListener() error {
if r.dontListen {
log.Infof(noCtx, "connection from external plugins disabled")
return nil
}
os.Remove(r.socketPath)
if err := os.MkdirAll(filepath.Dir(r.socketPath), 0700); err != nil {
return fmt.Errorf("failed to create socket %q: %w", r.socketPath, err)
}
l, err := net.ListenUnix("unix", &net.UnixAddr{
Name: r.socketPath,
Net: "unix",
})
if err != nil {
return fmt.Errorf("failed to create socket %q: %w", r.socketPath, err)
}
r.acceptPluginConnections(l)
return nil
}
func (r *Adaptation) stopListener() {
if r.listener != nil {
r.listener.Close()
}
}
func (r *Adaptation) acceptPluginConnections(l net.Listener) error {
r.listener = l
ctx := context.Background()
go func() {
for {
conn, err := l.Accept()
if err != nil {
log.Infof(ctx, "stopped accepting plugin connections (%v)", err)
return
}
p, err := r.newExternalPlugin(conn)
if err != nil {
log.Errorf(ctx, "failed to create external plugin: %v", err)
continue
}
if err := p.start(r.name, r.version); err != nil {
log.Errorf(ctx, "failed to start external plugin: %v", err)
continue
}
err = r.syncFn(ctx, p.synchronize)
if err != nil {
log.Infof(ctx, "failed to synchronize plugin: %v", err)
} else {
r.Lock()
r.plugins = append(r.plugins, p)
r.sortPlugins()
r.Unlock()
}
log.Infof(ctx, "plugin %q connected", p.name())
}
}()
return nil
}
func (r *Adaptation) discoverPlugins() ([]string, []string, []string, error) {
var (
plugins []string
indices []string
configs []string
entries []os.DirEntry
info fs.FileInfo
err error
)
if entries, err = os.ReadDir(r.pluginPath); err != nil {
if os.IsNotExist(err) {
return nil, nil, nil, nil
}
return nil, nil, nil, fmt.Errorf("failed to discover plugins in %s: %w",
r.pluginPath, err)
}
for _, e := range entries {
if e.IsDir() {
continue
}
if info, err = e.Info(); err != nil {
continue
}
if info.Mode()&fs.FileMode(0o111) == 0 {
continue
}
name := e.Name()
idx, base, err := api.ParsePluginName(name)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to discover plugins in %s: %w",
r.pluginPath, err)
}
cfg, err := r.getPluginConfig(idx, base)
if err != nil {
return nil, nil, nil, fmt.Errorf("failed to discover plugins in %s: %w",
r.pluginPath, err)
}
log.Infof(noCtx, "discovered plugin %s", name)
indices = append(indices, idx)
plugins = append(plugins, base)
configs = append(configs, cfg)
}
return indices, plugins, configs, nil
}
func (r *Adaptation) sortPlugins() {
r.removeClosedPlugins()
sort.Slice(r.plugins, func(i, j int) bool {
return r.plugins[i].idx < r.plugins[j].idx
})
if len(r.plugins) > 0 {
log.Infof(noCtx, "plugin invocation order")
for i, p := range r.plugins {
log.Infof(noCtx, " #%d: %q (%s)", i+1, p.name(), p.qualifiedName())
}
}
}
nri-0.6.1/pkg/adaptation/adaptation_suite_test.go 0000664 0000000 0000000 00000152354 14610311645 0022151 0 ustar 00root root 0000000 0000000 /*
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 adaptation_test
import (
"context"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"sigs.k8s.io/yaml"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
nri "github.com/containerd/nri/pkg/adaptation"
"github.com/containerd/nri/pkg/api"
)
var _ = Describe("Configuration", func() {
var (
s = &Suite{}
)
AfterEach(func() {
s.Cleanup()
})
When("no (extra) options given", func() {
BeforeEach(func() {
s.Prepare(&mockRuntime{}, &mockPlugin{idx: "00", name: "test"})
})
It("should allow startup", func() {
Expect(s.runtime.Start(s.dir)).To(Succeed())
})
It("should allow external plugins to connect", func() {
var (
runtime = s.runtime
plugin = s.plugins[0]
timeout = time.After(startupTimeout)
)
Expect(runtime.Start(s.dir)).To(Succeed())
Expect(plugin.Start(s.dir)).To(Succeed())
Expect(plugin.Wait(PluginSynchronized, timeout)).To(Succeed())
})
})
When("external connections are explicitly disabled", func() {
var ()
BeforeEach(func() {
s.Prepare(
&mockRuntime{
options: []nri.Option{
nri.WithDisabledExternalConnections(),
},
},
&mockPlugin{idx: "00", name: "test"},
)
})
It("should prevent plugins from connecting", func() {
var (
runtime = s.runtime
plugin = s.plugins[0]
)
Expect(runtime.Start(s.dir)).To(Succeed())
Expect(plugin.Start(s.dir)).ToNot(Succeed())
})
})
})
var _ = Describe("Adaptation", func() {
When("SyncFn is nil", func() {
var (
syncFn func(ctx context.Context, cb nri.SyncCB) error
updateFn = func(ctx context.Context, updates []*nri.ContainerUpdate) ([]*nri.ContainerUpdate, error) {
return nil, nil
}
)
It("should prevent Adaptation creation with an error", func() {
var (
dir = GinkgoT().TempDir()
etc = filepath.Join(dir, "etc", "nri")
)
Expect(os.MkdirAll(etc, 0o755)).To(Succeed())
r, err := nri.New("mockRuntime", "0.0.1", syncFn, updateFn,
nri.WithPluginPath(filepath.Join(dir, "opt", "nri", "plugins")),
nri.WithPluginConfigPath(filepath.Join(dir, "etc", "nri", "conf.d")),
nri.WithSocketPath(filepath.Join(dir, "nri.sock")),
)
Expect(r).To(BeNil())
Expect(err).ToNot(BeNil())
})
})
When("UpdateFn is nil", func() {
var (
updateFn func(ctx context.Context, updates []*nri.ContainerUpdate) ([]*nri.ContainerUpdate, error)
syncFn = func(ctx context.Context, cb nri.SyncCB) error {
return nil
}
)
It("should prevent Adaptation creation with an error", func() {
var (
dir = GinkgoT().TempDir()
etc = filepath.Join(dir, "etc", "nri")
)
Expect(os.MkdirAll(etc, 0o755)).To(Succeed())
r, err := nri.New("mockRuntime", "0.0.1", syncFn, updateFn,
nri.WithPluginPath(filepath.Join(dir, "opt", "nri", "plugins")),
nri.WithPluginConfigPath(filepath.Join(dir, "etc", "nri", "conf.d")),
nri.WithSocketPath(filepath.Join(dir, "nri.sock")),
)
Expect(r).To(BeNil())
Expect(err).ToNot(BeNil())
})
})
})
var _ = Describe("Plugin connection", func() {
var (
s = &Suite{}
)
BeforeEach(func() {
s.Prepare(
&mockRuntime{
pods: map[string]*api.PodSandbox{
"pod0": {
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
},
"pod1": {
Id: "pod1",
Name: "pod1",
Uid: "uid1",
Namespace: "default",
},
},
ctrs: map[string]*api.Container{
"ctr0": {
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED,
},
"ctr1": {
Id: "ctr1",
PodSandboxId: "pod1",
Name: "ctr1",
State: api.ContainerState_CONTAINER_CREATED,
},
},
},
&mockPlugin{
name: "test",
idx: "00",
},
)
})
AfterEach(func() {
s.Cleanup()
})
It("should configure the plugin", func() {
var (
plugin = s.plugins[0]
)
s.Startup()
Expect(plugin.Events()).Should(
ContainElement(
PluginConfigured,
),
)
})
It("should synchronize the plugin after configuration", func() {
var (
runtime = s.runtime
plugin = s.plugins[0]
)
s.Startup()
Expect(plugin.Events()).Should(
ConsistOf(
PluginConfigured,
PluginSynchronized,
),
)
runtime.pods = strip(runtime.pods, map[string]*api.PodSandbox{}).(map[string]*api.PodSandbox)
runtime.ctrs = strip(runtime.ctrs, map[string]*api.Container{}).(map[string]*api.Container)
plugin.pods = strip(plugin.pods, map[string]*api.PodSandbox{}).(map[string]*api.PodSandbox)
plugin.ctrs = strip(plugin.ctrs, map[string]*api.Container{}).(map[string]*api.Container)
Expect(plugin.pods["pod0"]).To(Equal(runtime.pods["pod0"]))
Expect(plugin.pods["pod1"]).To(Equal(runtime.pods["pod1"]))
Expect(plugin.ctrs["ctr0"]).To(Equal(runtime.ctrs["ctr0"]))
Expect(plugin.ctrs["ctr1"]).To(Equal(runtime.ctrs["ctr1"]))
})
})
var _ = Describe("Pod and container requests and events", func() {
var (
s = &Suite{}
)
AfterEach(func() {
s.Cleanup()
})
When("there are no plugins", func() {
BeforeEach(func() {
s.Prepare(&mockRuntime{})
})
It("should always succeed", func() {
var (
ctx = context.Background()
pod0 = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
pod1 = &api.PodSandbox{
Id: "pod1",
Name: "pod1",
Uid: "uid1",
Namespace: "default",
}
ctr0 = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
ctr1 = &api.Container{
Id: "ctr1",
PodSandboxId: "pod1",
Name: "ctr1",
State: api.ContainerState_CONTAINER_CREATED, // XXXX FIXME-kludge
}
)
s.Startup()
Expect(s.runtime.startStopPodAndContainer(ctx, pod0, ctr0)).To(Succeed())
Expect(s.runtime.startStopPodAndContainer(ctx, pod1, ctr1)).To(Succeed())
})
})
When("when there are plugins", func() {
BeforeEach(func() {
s.Prepare(&mockRuntime{}, &mockPlugin{idx: "00", name: "test"})
})
DescribeTable("should honor plugins' event subscriptions",
func(subscriptions ...string) {
var (
runtime = s.runtime
plugin = s.plugins[0]
ctx = context.Background()
pod = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
)
plugin.mask = api.MustParseEventMask(subscriptions...)
s.Startup()
Expect(runtime.startStopPodAndContainer(ctx, pod, ctr)).To(Succeed())
for _, events := range subscriptions {
for _, event := range strings.Split(events, ",") {
match := &Event{Type: EventType(event)}
Expect(plugin.EventQ().Has(match)).To(BeTrue())
}
}
},
Entry("with RunPodSandbox", "RunPodSandbox"),
Entry("with StopPodSandbox", "StopPodSandbox"),
Entry("with RemovePodSandbox", "RemovePodSandbox"),
Entry("with CreateContainer", "CreateContainer"),
Entry("with PostCreateContainer", "PostCreateContainer"),
Entry("with StartContainer", "StartContainer"),
Entry("with PostStartContainer", "PostStartContainer"),
Entry("with UpdateContainer", "UpdateContainer"),
Entry("with PostUpdateContainer", "PostUpdateContainer"),
Entry("with StopContainer", "StopContainer"),
Entry("with RemoveContainer", "RemoveContainer"),
Entry("with all pod events", "RunPodSandbox,StopPodSandbox,RemovePodSandbox"),
Entry("with all container requests", "CreateContainer,UpdateContainer,StopContainer"),
Entry("with all container requests and events",
"CreateContainer,PostCreateContainer",
"StartContainer,PostStartContainer",
"UpdateContainer,PostUpdateContainer",
"StopContainer",
"RemoveContainer",
),
Entry("with all pod and container requests and events",
"RunPodSandbox,StopPodSandbox,RemovePodSandbox",
"CreateContainer,PostCreateContainer",
"StartContainer,PostStartContainer",
"UpdateContainer,PostUpdateContainer",
"StopContainer",
"RemoveContainer",
),
)
})
When("when there are multiple plugins", func() {
BeforeEach(func() {
s.Prepare(
&mockRuntime{},
&mockPlugin{idx: "20", name: "test"},
&mockPlugin{idx: "99", name: "foo"},
&mockPlugin{idx: "00", name: "bar"},
)
})
DescribeTable("should honor plugins' event subscriptions",
func(subscriptions ...string) {
var (
runtime = s.runtime
plugins = s.plugins
ctx = context.Background()
pod = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
order []*mockPlugin
recordOrder = func(p *mockPlugin, pod *api.PodSandbox, ctr *api.Container) error {
order = append(order, p)
return nil
}
)
for _, p := range plugins {
p.mask = api.MustParseEventMask(subscriptions...)
p.startContainer = recordOrder
}
s.Startup()
Expect(runtime.startStopPodAndContainer(ctx, pod, ctr)).To(Succeed())
Expect(order).Should(
ConsistOf(
plugins[2],
plugins[0],
plugins[1],
),
)
},
Entry("with StartContainer", "StartContainer"),
Entry("with all container CRI requests",
"CreateContainer,StartContainer,UpdateContainer,StopContainer,RemoveContainer"),
Entry("with all container requests and events",
"CreateContainer,PostCreateContainer",
"StartContainer,PostStartContainer",
"UpdateContainer,PostUpdateContainer",
"StopContainer",
"RemoveContainer",
),
Entry("with all pod and container requests and events",
"RunPodSandbox,StopPodSandbox,RemovePodSandbox",
"CreateContainer,PostCreateContainer",
"StartContainer,PostStartContainer",
"UpdateContainer,PostUpdateContainer",
"StopContainer",
"RemoveContainer",
),
)
})
})
var _ = Describe("Plugin container creation adjustments", func() {
var (
s = &Suite{}
)
adjust := func(subject string, p *mockPlugin, pod *api.PodSandbox, ctr *api.Container, overwrite bool) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
plugin := p.idx + "-" + p.name
a := &api.ContainerAdjustment{}
switch subject {
case "annotation":
if overwrite {
a.RemoveAnnotation("key")
}
a.AddAnnotation("key", plugin)
case "mount":
mnt := &api.Mount{
Source: "/dev/" + plugin,
Destination: "/mnt/test",
}
if overwrite {
a.RemoveMount(mnt.Destination)
}
a.AddMount(mnt)
case "environment":
if overwrite {
a.RemoveEnv("key")
}
a.AddEnv("key", plugin)
case "hooks":
a.AddHooks(
&api.Hooks{
Prestart: []*api.Hook{
{
Path: "/bin/" + plugin,
},
},
},
)
case "device":
idx, _ := strconv.ParseInt(p.idx, 10, 64)
dev := &api.LinuxDevice{
Path: "/dev/test",
Type: "c",
Major: 313,
Minor: 100 + idx,
}
if overwrite {
a.RemoveDevice(dev.Path)
}
a.AddDevice(dev)
case "rlimit":
a.AddRlimit("nofile", 456, 123)
case "resources/cpu":
a.SetLinuxCPUShares(123)
a.SetLinuxCPUQuota(456)
a.SetLinuxCPUPeriod(789)
a.SetLinuxCPURealtimeRuntime(321)
a.SetLinuxCPURealtimePeriod(654)
a.SetLinuxCPUSetCPUs("0-1")
a.SetLinuxCPUSetMems("2-3")
case "resources/mem":
a.SetLinuxMemoryLimit(1234000)
a.SetLinuxMemoryReservation(4000)
a.SetLinuxMemorySwap(34000)
a.SetLinuxMemoryKernel(30000)
a.SetLinuxMemoryKernelTCP(2000)
a.SetLinuxMemorySwappiness(987)
a.SetLinuxMemoryDisableOomKiller()
a.SetLinuxMemoryUseHierarchy()
case "resources/classes":
a.SetLinuxRDTClass(plugin)
a.SetLinuxBlockIOClass(plugin)
case "resources/hugepagelimits":
a.AddLinuxHugepageLimit("1M", 4096)
a.AddLinuxHugepageLimit("4M", 1024)
case "resources/unified":
a.AddLinuxUnified("resource.1", "value1")
a.AddLinuxUnified("resource.2", "value2")
case "cgroupspath":
a.SetLinuxCgroupsPath("/" + plugin)
}
return a, nil, nil
}
AfterEach(func() {
s.Cleanup()
})
When("there is a single plugin", func() {
BeforeEach(func() {
s.Prepare(&mockRuntime{}, &mockPlugin{idx: "00", name: "test"})
})
DescribeTable("should be successfully collected without conflicts",
func(subject string, expected *api.ContainerAdjustment) {
var (
runtime = s.runtime
plugin = s.plugins[0]
ctx = context.Background()
pod = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
)
create := func(p *mockPlugin, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
return adjust(subject, p, pod, ctr, false)
}
plugin.createContainer = create
s.Startup()
podReq := &api.RunPodSandboxRequest{Pod: pod}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq := &api.CreateContainerRequest{
Pod: pod,
Container: ctr,
}
reply, err := runtime.runtime.CreateContainer(ctx, ctrReq)
Expect(err).To(BeNil())
Expect(stripAdjustment(reply.Adjust)).Should(Equal(stripAdjustment(expected)))
},
Entry("adjust annotations", "annotation",
&api.ContainerAdjustment{
Annotations: map[string]string{
"key": "00-test",
},
},
),
Entry("adjust mounts", "mount",
&api.ContainerAdjustment{
Mounts: []*api.Mount{
{
Source: "/dev/00-test",
Destination: "/mnt/test",
},
},
},
),
Entry("adjust environment", "environment",
&api.ContainerAdjustment{
Env: []*api.KeyValue{
{
Key: "key",
Value: "00-test",
},
},
},
),
Entry("adjust hooks", "hooks",
&api.ContainerAdjustment{
Hooks: &api.Hooks{
Prestart: []*api.Hook{
{
Path: "/bin/00-test",
},
},
},
},
),
Entry("adjust devices", "device",
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Devices: []*api.LinuxDevice{
{
Path: "/dev/test",
Type: "c",
Major: 313,
Minor: 100,
},
},
},
},
),
Entry("adjust rlimits", "rlimit",
&api.ContainerAdjustment{
Rlimits: []*api.POSIXRlimit{{Type: "nofile", Soft: 123, Hard: 456}},
},
),
Entry("adjust CPU resources", "resources/cpu",
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(123),
Quota: api.Int64(456),
Period: api.UInt64(789),
RealtimeRuntime: api.Int64(321),
RealtimePeriod: api.UInt64(654),
Cpus: "0-1",
Mems: "2-3",
},
},
},
},
),
Entry("adjust memory resources", "resources/mem",
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Memory: &api.LinuxMemory{
Limit: api.Int64(1234000),
Reservation: api.Int64(4000),
Swap: api.Int64(34000),
Kernel: api.Int64(30000),
KernelTcp: api.Int64(2000),
Swappiness: api.UInt64(987),
DisableOomKiller: api.Bool(true),
UseHierarchy: api.Bool(true),
},
},
},
},
),
Entry("adjust class-based resources", "resources/classes",
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
RdtClass: api.String("00-test"),
BlockioClass: api.String("00-test"),
},
},
},
),
Entry("adjust hugepage limits", "resources/hugepagelimits",
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
HugepageLimits: []*api.HugepageLimit{
{
PageSize: "1M",
Limit: 4096,
},
{
PageSize: "4M",
Limit: 1024,
},
},
},
},
},
),
Entry("adjust cgroupv2 unified resources", "resources/unified",
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Unified: map[string]string{
"resource.1": "value1",
"resource.2": "value2",
},
},
},
},
),
Entry("adjust cgroups path", "cgroupspath",
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
CgroupsPath: "/00-test",
},
},
),
)
})
When("there are multiple plugins", func() {
BeforeEach(func() {
s.Prepare(
&mockRuntime{},
&mockPlugin{idx: "10", name: "foo"},
&mockPlugin{idx: "00", name: "bar"},
)
})
DescribeTable("should be successfully combined if there are no conflicts",
func(subject string, remove, shouldFail bool, expected *api.ContainerAdjustment) {
var (
runtime = s.runtime
plugins = s.plugins
ctx = context.Background()
pod = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
)
create := func(p *mockPlugin, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
return adjust(subject, p, pod, ctr, p == plugins[0] && remove)
}
plugins[0].createContainer = create
plugins[1].createContainer = create
s.Startup()
podReq := &api.RunPodSandboxRequest{Pod: pod}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq := &api.CreateContainerRequest{
Pod: pod,
Container: ctr,
}
reply, err := runtime.runtime.CreateContainer(ctx, ctrReq)
if shouldFail {
Expect(err).ToNot(BeNil())
} else {
Expect(err).To(BeNil())
reply.Adjust = strip(reply.Adjust, &api.ContainerAdjustment{}).(*api.ContainerAdjustment)
Expect(stripAdjustment(reply.Adjust)).Should(Equal(stripAdjustment(expected)))
}
},
Entry("adjust annotations (conflicts)", "annotation", false, true, nil),
Entry("adjust annotations", "annotation", true, false,
&api.ContainerAdjustment{
Annotations: map[string]string{
"-key": "",
"key": "10-foo",
},
},
),
Entry("adjust mounts (conflicts)", "mount", false, true, nil),
Entry("adjust mounts", "mount", true, false,
&api.ContainerAdjustment{
Mounts: []*api.Mount{
{
Source: "/dev/10-foo",
Destination: "/mnt/test",
},
},
},
),
Entry("adjust environment (conflicts)", "environment", false, true, nil),
Entry("adjust environment", "environment", true, false,
&api.ContainerAdjustment{
Env: []*api.KeyValue{
{
Key: "key",
Value: "10-foo",
},
},
},
),
Entry("adjust hooks", "hooks", false, false,
&api.ContainerAdjustment{
Hooks: &api.Hooks{
Prestart: []*api.Hook{
{
Path: "/bin/00-bar",
},
{
Path: "/bin/10-foo",
},
},
},
},
),
Entry("adjust devices", "device", false, true, nil),
Entry("adjust devices", "device", true, false,
&api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Devices: []*api.LinuxDevice{
{
Path: "/dev/test",
Type: "c",
Major: 313,
Minor: 110,
},
},
},
},
),
Entry("adjust resources", "resources/classes", false, true, nil),
)
})
})
// --------------------------------------------
var _ = Describe("Plugin container updates during creation", func() {
var (
s = &Suite{}
)
update := func(subject, which string, p *mockPlugin, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
plugin := p.idx + "-" + p.name
if which != plugin && which != "*" && which != "both" {
return nil, nil, nil
}
if ctr.Name != "ctr1" {
return nil, nil, nil
}
u := &api.ContainerUpdate{}
u.SetContainerId("ctr0")
switch subject {
case "resources/cpu":
u.SetLinuxCPUShares(123)
u.SetLinuxCPUQuota(456)
u.SetLinuxCPUPeriod(789)
u.SetLinuxCPURealtimeRuntime(321)
u.SetLinuxCPURealtimePeriod(654)
u.SetLinuxCPUSetCPUs("0-1")
u.SetLinuxCPUSetMems("2-3")
case "resources/memory":
u.SetLinuxMemoryLimit(1234000)
u.SetLinuxMemoryReservation(4000)
u.SetLinuxMemorySwap(34000)
u.SetLinuxMemoryKernel(30000)
u.SetLinuxMemoryKernelTCP(2000)
u.SetLinuxMemorySwappiness(987)
u.SetLinuxMemoryDisableOomKiller()
u.SetLinuxMemoryUseHierarchy()
case "resources/classes":
u.SetLinuxRDTClass(plugin)
u.SetLinuxBlockIOClass(plugin)
case "resources/hugepagelimits":
u.AddLinuxHugepageLimit("1M", 4096)
u.AddLinuxHugepageLimit("4M", 1024)
case "resources/unified":
u.AddLinuxUnified("resource.1", "value1")
u.AddLinuxUnified("resource.2", "value2")
}
return nil, []*api.ContainerUpdate{u}, nil
}
AfterEach(func() {
s.Cleanup()
})
When("there is a single plugin", func() {
BeforeEach(func() {
s.Prepare(&mockRuntime{}, &mockPlugin{idx: "00", name: "test"})
})
DescribeTable("should be successfully collected without conflicts",
func(subject string, expected *api.ContainerUpdate) {
var (
runtime = s.runtime
plugin = s.plugins[0]
ctx = context.Background()
pod0 = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr0 = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
pod1 = &api.PodSandbox{
Id: "pod1",
Name: "pod1",
Uid: "uid1",
Namespace: "default",
}
ctr1 = &api.Container{
Id: "ctr1",
PodSandboxId: "pod1",
Name: "ctr1",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
reply *api.CreateContainerResponse
)
create := func(p *mockPlugin, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
plugin := p.idx + "-" + p.name
return update(subject, plugin, p, pod, ctr)
}
plugin.createContainer = create
s.Startup()
podReq := &api.RunPodSandboxRequest{Pod: pod0}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq := &api.CreateContainerRequest{
Pod: pod0,
Container: ctr0,
}
_, err := runtime.runtime.CreateContainer(ctx, ctrReq)
Expect(err).To(BeNil())
podReq = &api.RunPodSandboxRequest{Pod: pod1}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq = &api.CreateContainerRequest{
Pod: pod1,
Container: ctr1,
}
reply, err = runtime.runtime.CreateContainer(ctx, ctrReq)
Expect(err).To(BeNil())
Expect(len(reply.Update)).To(Equal(1))
expected.ContainerId = reply.Update[0].ContainerId
Expect(stripUpdate(reply.Update[0])).Should(Equal(stripUpdate(expected)))
},
Entry("update CPU resources", "resources/cpu",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(123),
Quota: api.Int64(456),
Period: api.UInt64(789),
RealtimeRuntime: api.Int64(321),
RealtimePeriod: api.UInt64(654),
Cpus: "0-1",
Mems: "2-3",
},
},
},
},
),
Entry("update memory resources", "resources/memory",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Memory: &api.LinuxMemory{
Limit: api.Int64(1234000),
Reservation: api.Int64(4000),
Swap: api.Int64(34000),
Kernel: api.Int64(30000),
KernelTcp: api.Int64(2000),
Swappiness: api.UInt64(987),
DisableOomKiller: api.Bool(true),
UseHierarchy: api.Bool(true),
},
},
},
},
),
Entry("update class-based resources", "resources/classes",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
RdtClass: api.String("00-test"),
BlockioClass: api.String("00-test"),
},
},
},
),
Entry("update hugepage limits", "resources/hugepagelimits",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
HugepageLimits: []*api.HugepageLimit{
{
PageSize: "1M",
Limit: 4096,
},
{
PageSize: "4M",
Limit: 1024,
},
},
},
},
},
),
Entry("update cgroupv2 unified resources", "resources/unified",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Unified: map[string]string{
"resource.1": "value1",
"resource.2": "value2",
},
},
},
},
),
)
})
When("there are multiple plugins", func() {
BeforeEach(func() {
s.Prepare(
&mockRuntime{},
&mockPlugin{idx: "10", name: "foo"},
&mockPlugin{idx: "00", name: "bar"},
)
})
DescribeTable("should fail with conflicts, successfully collected otherwise",
func(subject string, which string, expected *api.ContainerUpdate) {
var (
runtime = s.runtime
plugins = s.plugins
ctx = context.Background()
pod0 = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr0 = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
pod1 = &api.PodSandbox{
Id: "pod1",
Name: "pod1",
Uid: "uid1",
Namespace: "default",
}
ctr1 = &api.Container{
Id: "ctr1",
PodSandboxId: "pod1",
Name: "ctr1",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
reply *api.CreateContainerResponse
)
create := func(p *mockPlugin, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
return update(subject, which, p, pod, ctr)
}
plugins[0].createContainer = create
plugins[1].createContainer = create
s.Startup()
podReq := &api.RunPodSandboxRequest{Pod: pod0}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq := &api.CreateContainerRequest{
Pod: pod0,
Container: ctr0,
}
_, err := runtime.runtime.CreateContainer(ctx, ctrReq)
Expect(err).To(BeNil())
podReq = &api.RunPodSandboxRequest{Pod: pod1}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq = &api.CreateContainerRequest{
Pod: pod1,
Container: ctr1,
}
reply, err = runtime.runtime.CreateContainer(ctx, ctrReq)
if which == "both" {
Expect(err).ToNot(BeNil())
} else {
Expect(err).To(BeNil())
Expect(len(reply.Update)).To(Equal(1))
expected.ContainerId = reply.Update[0].ContainerId
Expect(stripUpdate(reply.Update[0])).Should(Equal(stripUpdate(expected)))
}
},
Entry("update CPU resources", "resources/cpu", "both", nil),
Entry("update CPU resources", "resources/cpu", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(123),
Quota: api.Int64(456),
Period: api.UInt64(789),
RealtimeRuntime: api.Int64(321),
RealtimePeriod: api.UInt64(654),
Cpus: "0-1",
Mems: "2-3",
},
},
},
},
),
Entry("update memory resources", "resources/memory", "both", nil),
Entry("update memory resources", "resources/memory", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Memory: &api.LinuxMemory{
Limit: api.Int64(1234000),
Reservation: api.Int64(4000),
Swap: api.Int64(34000),
Kernel: api.Int64(30000),
KernelTcp: api.Int64(2000),
Swappiness: api.UInt64(987),
DisableOomKiller: api.Bool(true),
UseHierarchy: api.Bool(true),
},
},
},
},
),
Entry("update class-based resources", "resources/classes", "both", nil),
Entry("update class-based resources", "resources/classes", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
RdtClass: api.String("10-foo"),
BlockioClass: api.String("10-foo"),
},
},
},
),
Entry("update hugepage limits", "resources/hugepagelimits", "both", nil),
Entry("update hugepage limits", "resources/hugepagelimits", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
HugepageLimits: []*api.HugepageLimit{
{
PageSize: "1M",
Limit: 4096,
},
{
PageSize: "4M",
Limit: 1024,
},
},
},
},
},
),
Entry("update cgroupv2 unified resources", "resources/unified", "both", nil),
Entry("update cgroupv2 unified resources", "resources/unified", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Unified: map[string]string{
"resource.1": "value1",
"resource.2": "value2",
},
},
},
},
),
)
})
})
var _ = Describe("Solicited container updates by plugins", func() {
var (
s = &Suite{}
)
update := func(subject, which string, p *mockPlugin, pod *api.PodSandbox, ctr *api.Container, r, exp *api.LinuxResources) ([]*api.ContainerUpdate, error) {
plugin := p.idx + "-" + p.name
if which != plugin && which != "*" && which != "both" {
return nil, nil
}
if ctr.Name != "ctr0" {
return nil, nil
}
u := &api.ContainerUpdate{}
u.SetContainerId(ctr.Id)
switch subject {
case "resources/cpu":
u.SetLinuxCPUShares(123)
u.SetLinuxCPUQuota(456)
u.SetLinuxCPUPeriod(789)
u.SetLinuxCPURealtimeRuntime(321)
u.SetLinuxCPURealtimePeriod(654)
u.SetLinuxCPUSetCPUs("0-1")
u.SetLinuxCPUSetMems("2-3")
case "resources/memory":
u.SetLinuxMemoryLimit(1234000)
u.SetLinuxMemoryReservation(4000)
u.SetLinuxMemorySwap(34000)
u.SetLinuxMemoryKernel(30000)
u.SetLinuxMemoryKernelTCP(2000)
u.SetLinuxMemorySwappiness(987)
u.SetLinuxMemoryDisableOomKiller()
u.SetLinuxMemoryUseHierarchy()
case "resources/classes":
u.SetLinuxRDTClass(plugin)
u.SetLinuxBlockIOClass(plugin)
case "resources/hugepagelimits":
u.AddLinuxHugepageLimit("1M", 4096)
u.AddLinuxHugepageLimit("4M", 1024)
case "resources/unified":
u.AddLinuxUnified("resource.1", "value1")
u.AddLinuxUnified("resource.2", "value2")
}
return []*api.ContainerUpdate{u}, nil
}
AfterEach(func() {
s.Cleanup()
})
When("there is a single plugin", func() {
BeforeEach(func() {
s.Prepare(&mockRuntime{}, &mockPlugin{idx: "00", name: "test"})
})
DescribeTable("should be successfully collected without conflicts",
func(subject string, expected *api.ContainerUpdate) {
var (
runtime = s.runtime
plugin = s.plugins[0]
ctx = context.Background()
pod0 = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr0 = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
reply *api.UpdateContainerResponse
)
updateContainer := func(p *mockPlugin, pod *api.PodSandbox, ctr *api.Container, r *api.LinuxResources) ([]*api.ContainerUpdate, error) {
plugin := p.idx + "-" + p.name
return update(subject, plugin, p, pod, ctr, r, nil)
}
plugin.updateContainer = updateContainer
s.Startup()
podReq := &api.RunPodSandboxRequest{Pod: pod0}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq := &api.CreateContainerRequest{
Pod: pod0,
Container: ctr0,
}
_, err := runtime.runtime.CreateContainer(ctx, ctrReq)
Expect(err).To(BeNil())
updReq := &api.UpdateContainerRequest{
Pod: pod0,
Container: ctr0,
LinuxResources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
},
}
reply, err = runtime.runtime.UpdateContainer(ctx, updReq)
Expect(len(reply.Update)).To(Equal(1))
Expect(err).To(BeNil())
expected.ContainerId = reply.Update[0].ContainerId
Expect(stripUpdate(reply.Update[0])).Should(Equal(stripUpdate(expected)))
},
Entry("update CPU resources", "resources/cpu",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(123),
Quota: api.Int64(456),
Period: api.UInt64(789),
RealtimeRuntime: api.Int64(321),
RealtimePeriod: api.UInt64(654),
Cpus: "0-1",
Mems: "2-3",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
},
},
},
),
Entry("update memory resources", "resources/memory",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(1234000),
Reservation: api.Int64(4000),
Swap: api.Int64(34000),
Kernel: api.Int64(30000),
KernelTcp: api.Int64(2000),
Swappiness: api.UInt64(987),
DisableOomKiller: api.Bool(true),
UseHierarchy: api.Bool(true),
},
},
},
},
),
Entry("update class-based resources", "resources/classes",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
RdtClass: api.String("00-test"),
BlockioClass: api.String("00-test"),
},
},
},
),
Entry("update hugepage limits", "resources/hugepagelimits",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
HugepageLimits: []*api.HugepageLimit{
{
PageSize: "1M",
Limit: 4096,
},
{
PageSize: "4M",
Limit: 1024,
},
},
},
},
},
),
Entry("update cgroupv2 unified resources", "resources/unified",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
Unified: map[string]string{
"resource.1": "value1",
"resource.2": "value2",
},
},
},
},
),
)
})
When("there are multiple plugins", func() {
BeforeEach(func() {
s.Prepare(
&mockRuntime{},
&mockPlugin{idx: "10", name: "foo"},
&mockPlugin{idx: "00", name: "bar"},
)
})
DescribeTable("should fail with conflicts, successfully collected otherwise",
func(subject string, which string, expected *api.ContainerUpdate) {
var (
runtime = s.runtime
plugins = s.plugins
ctx = context.Background()
pod0 = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr0 = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED, // XXX FIXME-kludge
}
reply *api.UpdateContainerResponse
)
updateContainer := func(p *mockPlugin, pod *api.PodSandbox, ctr *api.Container, r *api.LinuxResources) ([]*api.ContainerUpdate, error) {
return update(subject, which, p, pod, ctr, r, nil)
}
plugins[0].updateContainer = updateContainer
plugins[1].updateContainer = updateContainer
s.Startup()
podReq := &api.RunPodSandboxRequest{Pod: pod0}
Expect(runtime.runtime.RunPodSandbox(ctx, podReq)).To(Succeed())
ctrReq := &api.CreateContainerRequest{
Pod: pod0,
Container: ctr0,
}
_, err := runtime.runtime.CreateContainer(ctx, ctrReq)
Expect(err).To(BeNil())
updReq := &api.UpdateContainerRequest{
Pod: pod0,
Container: ctr0,
LinuxResources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
},
}
reply, err = runtime.runtime.UpdateContainer(ctx, updReq)
if which == "both" {
Expect(err).ToNot(BeNil())
} else {
Expect(err).To(BeNil())
Expect(len(reply.Update)).To(Equal(1))
expected.ContainerId = reply.Update[0].ContainerId
Expect(stripUpdate(reply.Update[0])).Should(Equal(stripUpdate(expected)))
}
},
Entry("update CPU resources", "resources/cpu", "both", nil),
Entry("update CPU resources", "resources/cpu", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(123),
Quota: api.Int64(456),
Period: api.UInt64(789),
RealtimeRuntime: api.Int64(321),
RealtimePeriod: api.UInt64(654),
Cpus: "0-1",
Mems: "2-3",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
},
},
},
),
Entry("update memory resources", "resources/memory", "both", nil),
Entry("update memory resources", "resources/memory", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(1234000),
Reservation: api.Int64(4000),
Swap: api.Int64(34000),
Kernel: api.Int64(30000),
KernelTcp: api.Int64(2000),
Swappiness: api.UInt64(987),
DisableOomKiller: api.Bool(true),
UseHierarchy: api.Bool(true),
},
},
},
},
),
Entry("update class-based resources", "resources/classes", "both", nil),
Entry("update class-based resources", "resources/classes", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
RdtClass: api.String("10-foo"),
BlockioClass: api.String("10-foo"),
},
},
},
),
Entry("update hugepage limits", "resources/hugepagelimits", "both", nil),
Entry("update hugepage limits", "resources/hugepagelimits", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
HugepageLimits: []*api.HugepageLimit{
{
PageSize: "1M",
Limit: 4096,
},
{
PageSize: "4M",
Limit: 1024,
},
},
},
},
},
),
Entry("update cgroupv2 unified resources", "resources/unified", "both", nil),
Entry("update cgroupv2 unified resources", "resources/unified", "10-foo",
&api.ContainerUpdate{
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(999),
Quota: api.Int64(888),
Period: api.UInt64(777),
RealtimeRuntime: api.Int64(666),
RealtimePeriod: api.UInt64(555),
Cpus: "444",
Mems: "333",
},
Memory: &api.LinuxMemory{
Limit: api.Int64(9999),
Reservation: api.Int64(8888),
Swap: api.Int64(7777),
Kernel: api.Int64(6666),
KernelTcp: api.Int64(5555),
Swappiness: api.UInt64(444),
DisableOomKiller: api.Bool(false),
UseHierarchy: api.Bool(false),
},
Unified: map[string]string{
"resource.1": "value1",
"resource.2": "value2",
},
},
},
},
),
)
})
})
var _ = Describe("Unsolicited container update requests", func() {
var (
s = &Suite{}
)
AfterEach(func() {
s.Cleanup()
})
When("there are plugins", func() {
BeforeEach(func() {
s.Prepare(&mockRuntime{}, &mockPlugin{idx: "00", name: "test"})
})
It("should fail gracefully without unstarted plugins", func() {
var (
plugin = s.plugins[0]
)
s.StartRuntime()
Expect(plugin.Init(s.Dir())).To(Succeed())
updates := []*api.ContainerUpdate{
{
ContainerId: "pod0",
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
RdtClass: api.String("test"),
},
},
},
}
_, err := plugin.stub.UpdateContainers(updates)
Expect(err).ToNot(BeNil())
})
It("should be delivered, without crash/panic", func() {
var (
runtime = s.runtime
plugin = s.plugins[0]
ctx = context.Background()
pod = &api.PodSandbox{
Id: "pod0",
Name: "pod0",
Uid: "uid0",
Namespace: "default",
}
ctr = &api.Container{
Id: "ctr0",
PodSandboxId: "pod0",
Name: "ctr0",
State: api.ContainerState_CONTAINER_CREATED,
}
recordedUpdates []*nri.ContainerUpdate
)
runtime.updateFn = func(ctx context.Context, updates []*nri.ContainerUpdate) ([]*nri.ContainerUpdate, error) {
recordedUpdates = updates
return nil, nil
}
s.Startup()
Expect(runtime.startStopPodAndContainer(ctx, pod, ctr)).To(Succeed())
requestedUpdates := []*api.ContainerUpdate{
{
ContainerId: "pod0",
Linux: &api.LinuxContainerUpdate{
Resources: &api.LinuxResources{
RdtClass: api.String("test"),
},
},
},
}
failed, err := plugin.stub.UpdateContainers(requestedUpdates)
Expect(failed).To(BeNil())
Expect(err).To(BeNil())
Expect(recordedUpdates).ToNot(Equal(requestedUpdates))
})
})
})
// Notes:
//
// XXX FIXME KLUDGE
// Ever since we had to switch from gogo/protobuf to google.golang.org/protobuf
// (from the gogo one), we can't turn off sizeCache and a few other generated
// unexported fields (or if we can, I failed to figure out so far how). In some
// of our test cases this gives a false positive in ginkgo.Expect/Equal combos,
// since that also checks unexported fields for equality. As a band-aid work-
// around we marshal then unmarshal compared objects in offending test cases to
// clear those unexported fields.
func strip(obj interface{}, ptr interface{}) interface{} {
bytes, err := yaml.Marshal(obj)
Expect(err).To(BeNil())
Expect(yaml.Unmarshal(bytes, ptr)).To(Succeed())
return ptr
}
func stripAdjustment(a *api.ContainerAdjustment) *api.ContainerAdjustment {
stripAnnotations(a)
stripMounts(a)
stripEnv(a)
stripHooks(a)
stripRlimits(a)
stripLinuxAdjustment(a)
return a
}
func stripAnnotations(a *api.ContainerAdjustment) {
if len(a.Annotations) == 0 {
a.Annotations = nil
}
}
func stripMounts(a *api.ContainerAdjustment) {
if len(a.Mounts) == 0 {
a.Mounts = nil
}
}
func stripEnv(a *api.ContainerAdjustment) {
if len(a.Env) == 0 {
a.Env = nil
}
}
func stripHooks(a *api.ContainerAdjustment) {
if a.Hooks == nil {
return
}
switch {
case len(a.Hooks.Prestart) > 0:
case len(a.Hooks.CreateRuntime) > 0:
case len(a.Hooks.CreateContainer) > 0:
case len(a.Hooks.StartContainer) > 0:
case len(a.Hooks.Poststart) > 0:
case len(a.Hooks.Poststop) > 0:
default:
a.Hooks = nil
}
}
func stripRlimits(a *api.ContainerAdjustment) {
if len(a.Rlimits) == 0 {
a.Rlimits = nil
}
}
func stripLinuxAdjustment(a *api.ContainerAdjustment) {
if a.Linux == nil {
return
}
stripLinuxDevices(a)
a.Linux.Resources = stripLinuxResources(a.Linux.Resources)
if a.Linux.Devices == nil && a.Linux.Resources == nil && a.Linux.CgroupsPath == "" {
a.Linux = nil
}
}
func stripLinuxDevices(a *api.ContainerAdjustment) {
if len(a.Linux.Devices) == 0 {
a.Linux.Devices = nil
}
}
func stripLinuxResources(r *api.LinuxResources) *api.LinuxResources {
if r == nil {
return nil
}
r.Memory = stripLinuxResourcesMemory(r.Memory)
r.Cpu = stripLinuxResourcesCpu(r.Cpu)
r.HugepageLimits = stripLinuxResourcesHugepageLimits(r.HugepageLimits)
r.Unified = stripLinuxResourcesUnified(r.Unified)
switch {
case r.Memory != nil:
return r
case r.Cpu != nil:
return r
case r.HugepageLimits != nil:
return r
case r.Unified != nil:
return r
case r.BlockioClass.GetValue() != "":
return r
case r.RdtClass.GetValue() != "":
return r
}
return nil
}
func stripLinuxResourcesMemory(m *api.LinuxMemory) *api.LinuxMemory {
if m == nil {
return nil
}
switch {
case m.Limit.GetValue() != 0:
return m
case m.Reservation.GetValue() != 0:
return m
case m.Swap.GetValue() != 0:
return m
case m.Kernel.GetValue() != 0:
return m
case m.KernelTcp.GetValue() != 0:
return m
case m.Swappiness.GetValue() != 0:
return m
case m.DisableOomKiller.GetValue():
return m
case m.UseHierarchy.GetValue():
return m
}
return nil
}
func stripLinuxResourcesCpu(c *api.LinuxCPU) *api.LinuxCPU {
if c == nil {
return nil
}
switch {
case c.Shares.GetValue() != 0:
return c
case c.Quota.GetValue() != 0:
return c
case c.Period.GetValue() != 0:
return c
case c.RealtimeRuntime.GetValue() != 0:
return c
case c.RealtimePeriod.GetValue() != 0:
return c
case c.Cpus != "":
return c
case c.Mems != "":
return c
}
return nil
}
func stripLinuxResourcesHugepageLimits(l []*api.HugepageLimit) []*api.HugepageLimit {
if len(l) == 0 {
return nil
}
return l
}
func stripLinuxResourcesUnified(u map[string]string) map[string]string {
if len(u) == 0 {
return nil
}
return u
}
func stripUpdate(u *api.ContainerUpdate) *api.ContainerUpdate {
if u == nil {
return nil
}
u.Linux = stripUpdateLinux(u.Linux)
if u.ContainerId == "" && u.Linux == nil && !u.IgnoreFailure {
return nil
}
return u
}
func stripUpdateLinux(l *api.LinuxContainerUpdate) *api.LinuxContainerUpdate {
if l == nil {
return nil
}
r := stripLinuxResources(l.Resources)
if r == nil {
return l
}
l.Resources = r
return l
}
nri-0.6.1/pkg/adaptation/api.go 0000664 0000000 0000000 00000013214 14610311645 0016315 0 ustar 00root root 0000000 0000000 /*
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 adaptation
import (
"github.com/containerd/nri/pkg/api"
)
//
// Alias types, consts and functions from api for the runtime.
//
// Aliased request/response/event types for api/api.proto.
// nolint
type (
RegisterPluginRequest = api.RegisterPluginRequest
RegisterPluginResponse = api.Empty
UpdateContainersRequest = api.UpdateContainersRequest
UpdateContainersResponse = api.UpdateContainersResponse
ConfigureRequest = api.ConfigureRequest
ConfigureResponse = api.ConfigureResponse
SynchronizeRequest = api.SynchronizeRequest
SynchronizeResponse = api.SynchronizeResponse
CreateContainerRequest = api.CreateContainerRequest
CreateContainerResponse = api.CreateContainerResponse
UpdateContainerRequest = api.UpdateContainerRequest
UpdateContainerResponse = api.UpdateContainerResponse
StopContainerRequest = api.StopContainerRequest
StopContainerResponse = api.StopContainerResponse
StateChangeEvent = api.StateChangeEvent
StateChangeResponse = api.StateChangeResponse
RunPodSandboxRequest = api.RunPodSandboxRequest
StopPodSandboxRequest = api.StopPodSandboxRequest
RemovePodSandboxRequest = api.RemovePodSandboxRequest
StartContainerRequest = api.StartContainerRequest
StartContainerResponse = api.StartContainerResponse
RemoveContainerRequest = api.RemoveContainerRequest
RemoveContainerResponse = api.RemoveContainerResponse
PostCreateContainerRequest = api.PostCreateContainerRequest
PostCreateContainerResponse = api.PostCreateContainerResponse
PostStartContainerRequest = api.PostStartContainerRequest
PostStartContainerResponse = api.PostStartContainerResponse
PostUpdateContainerRequest = api.PostUpdateContainerRequest
PostUpdateContainerResponse = api.PostUpdateContainerResponse
PodSandbox = api.PodSandbox
LinuxPodSandbox = api.LinuxPodSandbox
Container = api.Container
ContainerAdjustment = api.ContainerAdjustment
LinuxContainerAdjustment = api.LinuxContainerAdjustment
ContainerUpdate = api.ContainerUpdate
LinuxContainerUpdate = api.LinuxContainerUpdate
ContainerEviction = api.ContainerEviction
ContainerState = api.ContainerState
KeyValue = api.KeyValue
Mount = api.Mount
LinuxContainer = api.LinuxContainer
LinuxNamespace = api.LinuxNamespace
LinuxResources = api.LinuxResources
LinuxCPU = api.LinuxCPU
LinuxMemory = api.LinuxMemory
LinuxDevice = api.LinuxDevice
LinuxDeviceCgroup = api.LinuxDeviceCgroup
HugepageLimit = api.HugepageLimit
Hooks = api.Hooks
Hook = api.Hook
POSIXRlimit = api.POSIXRlimit
EventMask = api.EventMask
)
// Aliased consts for api/api.proto.
// nolint
const (
Event_UNKNOWN = api.Event_UNKNOWN
Event_RUN_POD_SANDBOX = api.Event_RUN_POD_SANDBOX
Event_STOP_POD_SANDBOX = api.Event_STOP_POD_SANDBOX
Event_REMOVE_POD_SANDBOX = api.Event_REMOVE_POD_SANDBOX
Event_CREATE_CONTAINER = api.Event_CREATE_CONTAINER
Event_POST_CREATE_CONTAINER = api.Event_POST_CREATE_CONTAINER
Event_START_CONTAINER = api.Event_START_CONTAINER
Event_POST_START_CONTAINER = api.Event_POST_START_CONTAINER
Event_UPDATE_CONTAINER = api.Event_UPDATE_CONTAINER
Event_POST_UPDATE_CONTAINER = api.Event_POST_UPDATE_CONTAINER
Event_STOP_CONTAINER = api.Event_STOP_CONTAINER
Event_REMOVE_CONTAINER = api.Event_REMOVE_CONTAINER
ValidEvents = api.ValidEvents
ContainerState_CONTAINER_UNKNOWN = api.ContainerState_CONTAINER_UNKNOWN
ContainerState_CONTAINER_CREATED = api.ContainerState_CONTAINER_CREATED
ContainerState_CONTAINER_PAUSED = api.ContainerState_CONTAINER_PAUSED
ContainerState_CONTAINER_RUNNING = api.ContainerState_CONTAINER_RUNNING
ContainerState_CONTAINER_STOPPED = api.ContainerState_CONTAINER_STOPPED
ContainerState_CONTAINER_EXITED = api.ContainerState_CONTAINER_STOPPED
)
// Aliased types for api/optional.go.
// nolint
type (
OptionalString = api.OptionalString
OptionalInt = api.OptionalInt
OptionalInt32 = api.OptionalInt32
OptionalUInt32 = api.OptionalUInt32
OptionalInt64 = api.OptionalInt64
OptionalUInt64 = api.OptionalUInt64
OptionalBool = api.OptionalBool
OptionalFileMode = api.OptionalFileMode
)
// Aliased functions for api/optional.go.
// nolint
var (
String = api.String
Int = api.Int
Int32 = api.Int32
UInt32 = api.UInt32
Int64 = api.Int64
UInt64 = api.UInt64
Bool = api.Bool
FileMode = api.FileMode
)
// Aliased functions for api/types.go.
// nolint
var (
FromOCIMounts = api.FromOCIMounts
FromOCIHooks = api.FromOCIHooks
FromOCILinuxNamespaces = api.FromOCILinuxNamespaces
FromOCILinuxDevices = api.FromOCILinuxDevices
FromOCILinuxResources = api.FromOCILinuxResources
DupStringSlice = api.DupStringSlice
DupStringMap = api.DupStringMap
IsMarkedForRemoval = api.IsMarkedForRemoval
MarkForRemoval = api.MarkForRemoval
)
nri-0.6.1/pkg/adaptation/plugin.go 0000664 0000000 0000000 00000031427 14610311645 0017050 0 ustar 00root root 0000000 0000000 /*
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 adaptation
import (
"context"
"errors"
"fmt"
stdnet "net"
"os"
"os/exec"
"path/filepath"
"strconv"
"sync"
"time"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/log"
"github.com/containerd/nri/pkg/net"
"github.com/containerd/nri/pkg/net/multiplex"
"github.com/containerd/ttrpc"
)
const (
// DefaultPluginRegistrationTimeout is the default timeout for plugin registration.
DefaultPluginRegistrationTimeout = 5 * time.Second
// DefaultPluginRequestTimeout is the default timeout for plugins to handle a request.
DefaultPluginRequestTimeout = 2 * time.Second
)
var (
pluginRegistrationTimeout = DefaultPluginRegistrationTimeout
pluginRequestTimeout = DefaultPluginRequestTimeout
timeoutCfgLock sync.RWMutex
)
type plugin struct {
sync.Mutex
idx string
base string
cfg string
pid int
cmd *exec.Cmd
mux multiplex.Mux
rpcc *ttrpc.Client
rpcl stdnet.Listener
rpcs *ttrpc.Server
events EventMask
closed bool
stub api.PluginService
regC chan error
closeC chan struct{}
r *Adaptation
}
// SetPluginRegistrationTimeout sets the timeout for plugin registration.
func SetPluginRegistrationTimeout(t time.Duration) {
timeoutCfgLock.Lock()
defer timeoutCfgLock.Unlock()
pluginRegistrationTimeout = t
}
func getPluginRegistrationTimeout() time.Duration {
timeoutCfgLock.RLock()
defer timeoutCfgLock.RUnlock()
return pluginRegistrationTimeout
}
// SetPluginRequestTimeout sets the timeout for plugins to handle a request.
func SetPluginRequestTimeout(t time.Duration) {
timeoutCfgLock.Lock()
defer timeoutCfgLock.Unlock()
pluginRequestTimeout = t
}
func getPluginRequestTimeout() time.Duration {
timeoutCfgLock.RLock()
defer timeoutCfgLock.RUnlock()
return pluginRequestTimeout
}
// Launch a pre-installed plugin with a pre-connected socketpair.
func (r *Adaptation) newLaunchedPlugin(dir, idx, base, cfg string) (p *plugin, retErr error) {
name := idx + "-" + base
sockets, err := net.NewSocketPair()
if err != nil {
return nil, fmt.Errorf("failed to create plugin connection for plugin %q: %w", name, err)
}
defer sockets.Close()
conn, err := sockets.LocalConn()
if err != nil {
return nil, fmt.Errorf("failed to set up local connection for plugin %q: %w", name, err)
}
peerFile := sockets.PeerFile()
defer func() {
peerFile.Close()
if retErr != nil {
conn.Close()
}
}()
cmd := exec.Command(filepath.Join(dir, name))
cmd.ExtraFiles = []*os.File{peerFile}
cmd.Env = []string{
api.PluginNameEnvVar + "=" + base,
api.PluginIdxEnvVar + "=" + idx,
api.PluginSocketEnvVar + "=3",
}
p = &plugin{
cfg: cfg,
cmd: cmd,
idx: idx,
base: base,
regC: make(chan error, 1),
closeC: make(chan struct{}),
r: r,
}
if err = p.cmd.Start(); err != nil {
return nil, fmt.Errorf("failed launch plugin %q: %w", p.name(), err)
}
if err = p.connect(conn); err != nil {
return nil, err
}
return p, nil
}
// Create a plugin (stub) for an accepted external plugin connection.
func (r *Adaptation) newExternalPlugin(conn stdnet.Conn) (p *plugin, retErr error) {
p = &plugin{
regC: make(chan error, 1),
closeC: make(chan struct{}),
r: r,
}
if err := p.connect(conn); err != nil {
return nil, err
}
return p, nil
}
// Get plugin-specific configuration for an NRI-launched plugin.
func (r *Adaptation) getPluginConfig(id, base string) (string, error) {
name := id + "-" + base
dropIns := []string{
filepath.Join(r.dropinPath, name+".conf"),
filepath.Join(r.dropinPath, base+".conf"),
}
for _, path := range dropIns {
buf, err := os.ReadFile(path)
if err == nil {
return string(buf), nil
}
if !os.IsNotExist(err) {
return "", fmt.Errorf("failed to read configuration for plugin %q: %w", name, err)
}
}
return "", nil
}
// Check if the plugin is external (was not launched by us).
func (p *plugin) isExternal() bool {
return p.cmd == nil
}
// 'connect' a plugin, setting up multiplexing on its socket.
func (p *plugin) connect(conn stdnet.Conn) (retErr error) {
mux := multiplex.Multiplex(conn, multiplex.WithBlockedRead())
defer func() {
if retErr != nil {
mux.Close()
}
}()
pconn, err := mux.Open(multiplex.PluginServiceConn)
if err != nil {
return fmt.Errorf("failed to mux plugin connection for plugin %q: %w", p.name(), err)
}
clientOpts := []ttrpc.ClientOpts{
ttrpc.WithOnClose(
func() {
log.Infof(noCtx, "connection to plugin %q closed", p.name())
close(p.closeC)
p.close()
}),
}
rpcc := ttrpc.NewClient(pconn, append(clientOpts, p.r.clientOpts...)...)
defer func() {
if retErr != nil {
rpcc.Close()
}
}()
stub := api.NewPluginClient(rpcc)
rpcs, err := ttrpc.NewServer(p.r.serverOpts...)
if err != nil {
return fmt.Errorf("failed to create ttrpc server for plugin %q: %w", p.name(), err)
}
defer func() {
if retErr != nil {
rpcs.Close()
}
}()
rpcl, err := mux.Listen(multiplex.RuntimeServiceConn)
if err != nil {
return fmt.Errorf("failed to create mux runtime listener for plugin %q: %w", p.name(), err)
}
p.mux = mux
p.rpcc = rpcc
p.rpcl = rpcl
p.rpcs = rpcs
p.stub = stub
p.pid, err = getPeerPid(p.mux.Trunk())
if err != nil {
log.Warnf(noCtx, "failed to determine plugin pid pid: %v", err)
}
api.RegisterRuntimeService(p.rpcs, p)
return nil
}
// Start Runtime service, wait for plugin to register, then configure it.
func (p *plugin) start(name, version string) error {
var (
err error
timeout = getPluginRegistrationTimeout()
)
go func() {
err := p.rpcs.Serve(context.Background(), p.rpcl)
if err != ttrpc.ErrServerClosed {
log.Infof(noCtx, "ttrpc server for plugin %q closed (%v)", p.name(), err)
}
p.close()
}()
p.mux.Unblock()
select {
case err = <-p.regC:
if err != nil {
return fmt.Errorf("failed to register plugin: %w", err)
}
case <-p.closeC:
return fmt.Errorf("failed to register plugin, connection closed")
case <-time.After(timeout):
p.close()
p.stop()
return errors.New("plugin registration timed out")
}
err = p.configure(context.Background(), name, version, p.cfg)
if err != nil {
p.close()
p.stop()
return err
}
return nil
}
// close a plugin shutting down its multiplexed ttrpc connections.
func (p *plugin) close() {
p.Lock()
defer p.Unlock()
if p.closed {
return
}
p.closed = true
p.mux.Close()
p.rpcc.Close()
p.rpcs.Close()
p.rpcl.Close()
}
func (p *plugin) isClosed() bool {
p.Lock()
defer p.Unlock()
return p.closed
}
// stop a plugin (if it was launched by us)
func (p *plugin) stop() error {
if p.isExternal() || p.cmd.Process == nil {
return nil
}
// TODO(klihub):
// We should attempt a graceful shutdown of the process here...
// - send it SIGINT
// - give the it some slack waiting with a timeout
// - butcher it with SIGKILL after the timeout
p.cmd.Process.Kill()
p.cmd.Process.Wait()
p.cmd.Process.Release()
return nil
}
// Name returns a string indentication for the plugin.
func (p *plugin) name() string {
return p.idx + "-" + p.base
}
func (p *plugin) qualifiedName() string {
var kind, idx, base string
if p.isExternal() {
kind = "external"
} else {
kind = "pre-connected"
}
if idx = p.idx; idx == "" {
idx = "??"
}
if base = p.base; base == "" {
base = "plugin"
}
return kind + ":" + idx + "-" + base + "[" + strconv.Itoa(p.pid) + "]"
}
// RegisterPlugin handles the plugin's registration request.
func (p *plugin) RegisterPlugin(ctx context.Context, req *RegisterPluginRequest) (*RegisterPluginResponse, error) {
if p.isExternal() {
if req.PluginName == "" {
p.regC <- fmt.Errorf("plugin %q registered empty name", p.qualifiedName())
return &RegisterPluginResponse{}, errors.New("invalid (empty) plugin name")
}
if err := api.CheckPluginIndex(req.PluginIdx); err != nil {
p.regC <- fmt.Errorf("plugin %q registered invalid index: %w", req.PluginName, err)
return &RegisterPluginResponse{}, fmt.Errorf("invalid plugin index: %w", err)
}
p.base = req.PluginName
p.idx = req.PluginIdx
}
log.Infof(ctx, "plugin %q registered as %q", p.qualifiedName(), p.name())
p.regC <- nil
return &RegisterPluginResponse{}, nil
}
// UpdateContainers relays container update request to the runtime.
func (p *plugin) UpdateContainers(ctx context.Context, req *UpdateContainersRequest) (*UpdateContainersResponse, error) {
log.Infof(ctx, "plugin %q requested container updates", p.name())
failed, err := p.r.updateContainers(ctx, req.Update)
return &UpdateContainersResponse{
Failed: failed,
}, err
}
// configure the plugin and subscribe it for the events it requested.
func (p *plugin) configure(ctx context.Context, name, version, config string) error {
ctx, cancel := context.WithTimeout(ctx, getPluginRequestTimeout())
defer cancel()
rpl, err := p.stub.Configure(ctx, &ConfigureRequest{
Config: config,
RuntimeName: name,
RuntimeVersion: version,
})
if err != nil {
return fmt.Errorf("failed to configure plugin: %w", err)
}
events := EventMask(rpl.Events)
if events != 0 {
if extra := events &^ ValidEvents; extra != 0 {
return fmt.Errorf("invalid plugin events: 0x%x", extra)
}
} else {
events = ValidEvents
}
p.events = events
return nil
}
// synchronize the plugin with the current state of the runtime.
func (p *plugin) synchronize(ctx context.Context, pods []*PodSandbox, containers []*Container) ([]*ContainerUpdate, error) {
log.Infof(ctx, "synchronizing plugin %s", p.name())
ctx, cancel := context.WithTimeout(ctx, getPluginRequestTimeout())
defer cancel()
req := &SynchronizeRequest{
Pods: pods,
Containers: containers,
}
rpl, err := p.stub.Synchronize(ctx, req)
if err != nil {
return nil, err
}
return rpl.Update, nil
}
// Relay CreateContainer request to plugin.
func (p *plugin) createContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) {
if !p.events.IsSet(Event_CREATE_CONTAINER) {
return nil, nil
}
ctx, cancel := context.WithTimeout(ctx, getPluginRequestTimeout())
defer cancel()
rpl, err := p.stub.CreateContainer(ctx, req)
if err != nil {
if isFatalError(err) {
log.Errorf(ctx, "closing plugin %s, failed to handle CreateContainer request: %v",
p.name(), err)
p.close()
return nil, nil
}
return nil, err
}
return rpl, nil
}
// Relay UpdateContainer request to plugin.
func (p *plugin) updateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) {
if !p.events.IsSet(Event_UPDATE_CONTAINER) {
return nil, nil
}
ctx, cancel := context.WithTimeout(ctx, getPluginRequestTimeout())
defer cancel()
rpl, err := p.stub.UpdateContainer(ctx, req)
if err != nil {
if isFatalError(err) {
log.Errorf(ctx, "closing plugin %s, failed to handle UpdateContainer request: %v",
p.name(), err)
p.close()
return nil, nil
}
return nil, err
}
return rpl, nil
}
// Relay StopContainer request to the plugin.
func (p *plugin) stopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) {
if !p.events.IsSet(Event_STOP_CONTAINER) {
return nil, nil
}
ctx, cancel := context.WithTimeout(ctx, getPluginRequestTimeout())
defer cancel()
rpl, err := p.stub.StopContainer(ctx, req)
if err != nil {
if isFatalError(err) {
log.Errorf(ctx, "closing plugin %s, failed to handle StopContainer request: %v",
p.name(), err)
p.close()
return nil, nil
}
return nil, err
}
return rpl, nil
}
// Relay other pod or container state change events to the plugin.
func (p *plugin) StateChange(ctx context.Context, evt *StateChangeEvent) error {
if !p.events.IsSet(evt.Event) {
return nil
}
ctx, cancel := context.WithTimeout(ctx, getPluginRequestTimeout())
defer cancel()
_, err := p.stub.StateChange(ctx, evt)
if err != nil {
if isFatalError(err) {
log.Errorf(ctx, "closing plugin %s, failed to handle event %d: %v",
p.name(), evt.Event, err)
p.close()
return nil
}
return err
}
return nil
}
// isFatalError returns true if the error is fatal and the plugin connection shoudld be closed.
func isFatalError(err error) bool {
switch {
case errors.Is(err, ttrpc.ErrClosed):
return true
case errors.Is(err, ttrpc.ErrServerClosed):
return true
case errors.Is(err, ttrpc.ErrProtocol):
return true
case errors.Is(err, context.DeadlineExceeded):
return true
}
return false
}
nri-0.6.1/pkg/adaptation/plugin_linux.go 0000664 0000000 0000000 00000002623 14610311645 0020263 0 ustar 00root root 0000000 0000000 //go:build linux
/*
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 adaptation
import (
"errors"
"fmt"
stdnet "net"
"golang.org/x/sys/unix"
)
// getPeerPid returns the process id at the other end of the connection.
func getPeerPid(conn stdnet.Conn) (int, error) {
var cred *unix.Ucred
uc, ok := conn.(*stdnet.UnixConn)
if !ok {
return 0, errors.New("invalid connection, not *net.UnixConn")
}
raw, err := uc.SyscallConn()
if err != nil {
return 0, fmt.Errorf("failed get raw unix domain connection: %w", err)
}
ctrlErr := raw.Control(func(fd uintptr) {
cred, err = unix.GetsockoptUcred(int(fd), unix.SOL_SOCKET, unix.SO_PEERCRED)
})
if err != nil {
return 0, fmt.Errorf("failed to get process credentials: %w", err)
}
if ctrlErr != nil {
return 0, fmt.Errorf("uc.SyscallConn().Control() failed: %w", ctrlErr)
}
return int(cred.Pid), nil
}
nri-0.6.1/pkg/adaptation/plugin_other.go 0000664 0000000 0000000 00000001541 14610311645 0020243 0 ustar 00root root 0000000 0000000 //go:build !linux
/*
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 adaptation
import (
"fmt"
"net"
"runtime"
)
// getPeerPid returns the process id at the other end of the connection.
func getPeerPid(conn net.Conn) (int, error) {
return 0, fmt.Errorf("getPeerPid() unimplemented on %s", runtime.GOOS)
}
nri-0.6.1/pkg/adaptation/result.go 0000664 0000000 0000000 00000102333 14610311645 0017063 0 ustar 00root root 0000000 0000000 /*
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 adaptation
import (
"fmt"
"strings"
)
type result struct {
request resultRequest
reply resultReply
updates map[string]*ContainerUpdate
owners resultOwners
}
type resultRequest struct {
create *CreateContainerRequest
update *UpdateContainerRequest
}
type resultReply struct {
adjust *ContainerAdjustment
update []*ContainerUpdate
}
type resultOwners map[string]*owners
func collectCreateContainerResult(request *CreateContainerRequest) *result {
if request.Container.Labels == nil {
request.Container.Labels = map[string]string{}
}
if request.Container.Annotations == nil {
request.Container.Annotations = map[string]string{}
}
if request.Container.Mounts == nil {
request.Container.Mounts = []*Mount{}
}
if request.Container.Env == nil {
request.Container.Env = []string{}
}
if request.Container.Hooks == nil {
request.Container.Hooks = &Hooks{}
}
if request.Container.Rlimits == nil {
request.Container.Rlimits = []*POSIXRlimit{}
}
if request.Container.Linux == nil {
request.Container.Linux = &LinuxContainer{}
}
if request.Container.Linux.Devices == nil {
request.Container.Linux.Devices = []*LinuxDevice{}
}
if request.Container.Linux.Resources == nil {
request.Container.Linux.Resources = &LinuxResources{}
}
if request.Container.Linux.Resources.Memory == nil {
request.Container.Linux.Resources.Memory = &LinuxMemory{}
}
if request.Container.Linux.Resources.Cpu == nil {
request.Container.Linux.Resources.Cpu = &LinuxCPU{}
}
if request.Container.Linux.Resources.Unified == nil {
request.Container.Linux.Resources.Unified = map[string]string{}
}
return &result{
request: resultRequest{
create: request,
},
reply: resultReply{
adjust: &ContainerAdjustment{
Annotations: map[string]string{},
Mounts: []*Mount{},
Env: []*KeyValue{},
Hooks: &Hooks{},
Rlimits: []*POSIXRlimit{},
Linux: &LinuxContainerAdjustment{
Devices: []*LinuxDevice{},
Resources: &LinuxResources{
Memory: &LinuxMemory{},
Cpu: &LinuxCPU{},
HugepageLimits: []*HugepageLimit{},
Unified: map[string]string{},
},
},
},
},
updates: map[string]*ContainerUpdate{},
owners: resultOwners{},
}
}
func collectUpdateContainerResult(request *UpdateContainerRequest) *result {
if request != nil {
if request.LinuxResources == nil {
request.LinuxResources = &LinuxResources{}
}
if request.LinuxResources.Memory == nil {
request.LinuxResources.Memory = &LinuxMemory{}
}
if request.LinuxResources.Cpu == nil {
request.LinuxResources.Cpu = &LinuxCPU{}
}
}
return &result{
request: resultRequest{
update: request,
},
reply: resultReply{
update: []*ContainerUpdate{},
},
updates: map[string]*ContainerUpdate{},
owners: resultOwners{},
}
}
func collectStopContainerResult() *result {
return collectUpdateContainerResult(nil)
}
func (r *result) createContainerResponse() *CreateContainerResponse {
return &CreateContainerResponse{
Adjust: r.reply.adjust,
Update: r.reply.update,
}
}
func (r *result) updateContainerResponse() *UpdateContainerResponse {
requested := r.updates[r.request.update.Container.Id]
return &UpdateContainerResponse{
Update: append(r.reply.update, requested),
}
}
func (r *result) stopContainerResponse() *StopContainerResponse {
return &StopContainerResponse{
Update: r.reply.update,
}
}
func (r *result) apply(response interface{}, plugin string) error {
switch rpl := response.(type) {
case *CreateContainerResponse:
if rpl == nil {
return nil
}
if err := r.adjust(rpl.Adjust, plugin); err != nil {
return err
}
if err := r.update(rpl.Update, plugin); err != nil {
return err
}
case *UpdateContainerResponse:
if rpl == nil {
return nil
}
if err := r.update(rpl.Update, plugin); err != nil {
return err
}
case *StopContainerResponse:
if rpl == nil {
return nil
}
if err := r.update(rpl.Update, plugin); err != nil {
return err
}
default:
return fmt.Errorf("cannot apply response of invalid type %T", response)
}
return nil
}
func (r *result) adjust(rpl *ContainerAdjustment, plugin string) error {
if rpl == nil {
return nil
}
if err := r.adjustAnnotations(rpl.Annotations, plugin); err != nil {
return err
}
if err := r.adjustMounts(rpl.Mounts, plugin); err != nil {
return err
}
if err := r.adjustEnv(rpl.Env, plugin); err != nil {
return err
}
if err := r.adjustHooks(rpl.Hooks, plugin); err != nil {
return err
}
if rpl.Linux != nil {
if err := r.adjustDevices(rpl.Linux.Devices, plugin); err != nil {
return err
}
if err := r.adjustResources(rpl.Linux.Resources, plugin); err != nil {
return err
}
if err := r.adjustCgroupsPath(rpl.Linux.CgroupsPath, plugin); err != nil {
return err
}
}
if err := r.adjustRlimits(rpl.Rlimits, plugin); err != nil {
return err
}
return nil
}
func (r *result) update(updates []*ContainerUpdate, plugin string) error {
for _, u := range updates {
reply, err := r.getContainerUpdate(u, plugin)
if err != nil {
return err
}
if err := r.updateResources(reply, u, plugin); err != nil && !u.IgnoreFailure {
return err
}
}
return nil
}
func (r *result) adjustAnnotations(annotations map[string]string, plugin string) error {
if len(annotations) == 0 {
return nil
}
create, id := r.request.create, r.request.create.Container.Id
del := map[string]struct{}{}
for k := range annotations {
if key, marked := IsMarkedForRemoval(k); marked {
del[key] = struct{}{}
delete(annotations, k)
}
}
for k, v := range annotations {
if _, ok := del[k]; ok {
r.owners.clearAnnotation(id, k)
delete(create.Container.Annotations, k)
r.reply.adjust.Annotations[MarkForRemoval(k)] = ""
}
if err := r.owners.claimAnnotation(id, k, plugin); err != nil {
return err
}
create.Container.Annotations[k] = v
r.reply.adjust.Annotations[k] = v
delete(del, k)
}
for k := range del {
r.reply.adjust.Annotations[MarkForRemoval(k)] = ""
}
return nil
}
func (r *result) adjustMounts(mounts []*Mount, plugin string) error {
if len(mounts) == 0 {
return nil
}
create, id := r.request.create, r.request.create.Container.Id
// first split removals from the rest of adjustments
add := []*Mount{}
del := map[string]*Mount{}
mod := map[string]*Mount{}
for _, m := range mounts {
if key, marked := m.IsMarkedForRemoval(); marked {
del[key] = m
} else {
add = append(add, m)
mod[key] = m
}
}
// next remove marked mounts from collected adjustments
cleared := []*Mount{}
for _, m := range r.reply.adjust.Mounts {
if _, removed := del[m.Destination]; removed {
r.owners.clearMount(id, m.Destination)
continue
}
cleared = append(cleared, m)
}
r.reply.adjust.Mounts = cleared
// next remove marked and modified mounts from container creation request
cleared = []*Mount{}
for _, m := range create.Container.Mounts {
if _, removed := del[m.Destination]; removed {
continue
}
if _, modified := mod[m.Destination]; modified {
continue
}
cleared = append(cleared, m)
}
create.Container.Mounts = cleared
// next, apply additions/modifications to collected adjustments
for _, m := range add {
if err := r.owners.claimMount(id, m.Destination, plugin); err != nil {
return err
}
r.reply.adjust.Mounts = append(r.reply.adjust.Mounts, m)
}
// finally, apply additions/modifications to plugin container creation request
create.Container.Mounts = append(create.Container.Mounts, add...)
return nil
}
func (r *result) adjustDevices(devices []*LinuxDevice, plugin string) error {
if len(devices) == 0 {
return nil
}
create, id := r.request.create, r.request.create.Container.Id
// first split removals from the rest of adjustments
add := []*LinuxDevice{}
del := map[string]*LinuxDevice{}
mod := map[string]*LinuxDevice{}
for _, d := range devices {
if key, marked := d.IsMarkedForRemoval(); marked {
del[key] = d
} else {
add = append(add, d)
mod[key] = d
}
}
// next remove marked devices from collected adjustments
cleared := []*LinuxDevice{}
for _, d := range r.reply.adjust.Linux.Devices {
if _, removed := del[d.Path]; removed {
r.owners.clearDevice(id, d.Path)
continue
}
cleared = append(cleared, d)
}
r.reply.adjust.Linux.Devices = cleared
// next remove marked and modified devices from container creation request
cleared = []*LinuxDevice{}
for _, d := range create.Container.Linux.Devices {
if _, removed := del[d.Path]; removed {
continue
}
if _, modified := mod[d.Path]; modified {
continue
}
cleared = append(cleared, d)
}
create.Container.Linux.Devices = cleared
// next, apply additions/modifications to collected adjustments
for _, d := range add {
if err := r.owners.claimDevice(id, d.Path, plugin); err != nil {
return err
}
r.reply.adjust.Linux.Devices = append(r.reply.adjust.Linux.Devices, d)
}
// finally, apply additions/modifications to plugin container creation request
create.Container.Linux.Devices = append(create.Container.Linux.Devices, add...)
return nil
}
func (r *result) adjustEnv(env []*KeyValue, plugin string) error {
if len(env) == 0 {
return nil
}
create, id := r.request.create, r.request.create.Container.Id
// first split removals from the rest of adjustments
add := []*KeyValue{}
del := map[string]struct{}{}
mod := map[string]struct{}{}
for _, e := range env {
if key, marked := e.IsMarkedForRemoval(); marked {
del[key] = struct{}{}
} else {
add = append(add, e)
mod[key] = struct{}{}
}
}
// next remove marked environment variables from collected adjustments
cleared := []*KeyValue{}
for _, e := range r.reply.adjust.Env {
if _, removed := del[e.Key]; removed {
r.owners.clearEnv(id, e.Key)
continue
}
cleared = append(cleared, e)
}
r.reply.adjust.Env = cleared
// next remove marked and modified environment from container creation request
clearedEnv := []string{}
for _, e := range create.Container.Env {
key, _ := splitEnvVar(e)
if _, removed := del[key]; removed {
continue
}
if _, modified := mod[key]; modified {
continue
}
clearedEnv = append(clearedEnv, e)
}
create.Container.Env = clearedEnv
// next, apply additions/modifications to collected adjustments
for _, e := range add {
if err := r.owners.claimEnv(id, e.Key, plugin); err != nil {
return err
}
r.reply.adjust.Env = append(r.reply.adjust.Env, e)
}
// finally, apply additions/modifications to plugin container creation request
for _, e := range add {
create.Container.Env = append(create.Container.Env, e.ToOCI())
}
return nil
}
func splitEnvVar(s string) (string, string) {
split := strings.SplitN(s, "=", 2)
if len(split) < 1 {
return "", ""
}
if len(split) != 2 {
return split[0], ""
}
return split[0], split[1]
}
func (r *result) adjustHooks(hooks *Hooks, plugin string) error {
if hooks == nil {
return nil
}
reply := r.reply.adjust
container := r.request.create.Container
if h := hooks.Prestart; len(h) > 0 {
reply.Hooks.Prestart = append(reply.Hooks.Prestart, h...)
container.Hooks.Prestart = append(container.Hooks.Prestart, h...)
}
if h := hooks.Poststart; len(h) > 0 {
reply.Hooks.Poststart = append(reply.Hooks.Poststart, h...)
container.Hooks.Poststart = append(container.Hooks.Poststart, h...)
}
if h := hooks.Poststop; len(h) > 0 {
reply.Hooks.Poststop = append(reply.Hooks.Poststop, h...)
container.Hooks.Poststop = append(container.Hooks.Poststop, h...)
}
if h := hooks.CreateRuntime; len(h) > 0 {
reply.Hooks.CreateRuntime = append(reply.Hooks.CreateRuntime, h...)
container.Hooks.CreateRuntime = append(container.Hooks.CreateRuntime, h...)
}
if h := hooks.CreateContainer; len(h) > 0 {
reply.Hooks.CreateContainer = append(reply.Hooks.CreateContainer, h...)
container.Hooks.CreateContainer = append(container.Hooks.CreateContainer, h...)
}
if h := hooks.StartContainer; len(h) > 0 {
reply.Hooks.StartContainer = append(reply.Hooks.StartContainer, h...)
container.Hooks.StartContainer = append(container.Hooks.StartContainer, h...)
}
return nil
}
func (r *result) adjustResources(resources *LinuxResources, plugin string) error {
if resources == nil {
return nil
}
create, id := r.request.create, r.request.create.Container.Id
container := create.Container.Linux.Resources
reply := r.reply.adjust.Linux.Resources
if mem := resources.Memory; mem != nil {
if v := mem.GetLimit(); v != nil {
if err := r.owners.claimMemLimit(id, plugin); err != nil {
return err
}
container.Memory.Limit = Int64(v.GetValue())
reply.Memory.Limit = Int64(v.GetValue())
}
if v := mem.GetReservation(); v != nil {
if err := r.owners.claimMemReservation(id, plugin); err != nil {
return err
}
container.Memory.Reservation = Int64(v.GetValue())
reply.Memory.Reservation = Int64(v.GetValue())
}
if v := mem.GetSwap(); v != nil {
if err := r.owners.claimMemSwapLimit(id, plugin); err != nil {
return err
}
container.Memory.Swap = Int64(v.GetValue())
reply.Memory.Swap = Int64(v.GetValue())
}
if v := mem.GetKernel(); v != nil {
if err := r.owners.claimMemKernelLimit(id, plugin); err != nil {
return err
}
container.Memory.Kernel = Int64(v.GetValue())
reply.Memory.Kernel = Int64(v.GetValue())
}
if v := mem.GetKernelTcp(); v != nil {
if err := r.owners.claimMemTCPLimit(id, plugin); err != nil {
return err
}
container.Memory.KernelTcp = Int64(v.GetValue())
reply.Memory.KernelTcp = Int64(v.GetValue())
}
if v := mem.GetSwappiness(); v != nil {
if err := r.owners.claimMemSwappiness(id, plugin); err != nil {
return err
}
container.Memory.Swappiness = UInt64(v.GetValue())
reply.Memory.Swappiness = UInt64(v.GetValue())
}
if v := mem.GetDisableOomKiller(); v != nil {
if err := r.owners.claimMemDisableOomKiller(id, plugin); err != nil {
return err
}
container.Memory.DisableOomKiller = Bool(v.GetValue())
reply.Memory.DisableOomKiller = Bool(v.GetValue())
}
if v := mem.GetUseHierarchy(); v != nil {
if err := r.owners.claimMemUseHierarchy(id, plugin); err != nil {
return err
}
container.Memory.UseHierarchy = Bool(v.GetValue())
reply.Memory.UseHierarchy = Bool(v.GetValue())
}
}
if cpu := resources.Cpu; cpu != nil {
if v := cpu.GetShares(); v != nil {
if err := r.owners.claimCpuShares(id, plugin); err != nil {
return err
}
container.Cpu.Shares = UInt64(v.GetValue())
reply.Cpu.Shares = UInt64(v.GetValue())
}
if v := cpu.GetQuota(); v != nil {
if err := r.owners.claimCpuQuota(id, plugin); err != nil {
return err
}
container.Cpu.Quota = Int64(v.GetValue())
reply.Cpu.Quota = Int64(v.GetValue())
}
if v := cpu.GetPeriod(); v != nil {
if err := r.owners.claimCpuPeriod(id, plugin); err != nil {
return err
}
container.Cpu.Period = UInt64(v.GetValue())
reply.Cpu.Period = UInt64(v.GetValue())
}
if v := cpu.GetRealtimeRuntime(); v != nil {
if err := r.owners.claimCpuRealtimeRuntime(id, plugin); err != nil {
return err
}
container.Cpu.RealtimeRuntime = Int64(v.GetValue())
reply.Cpu.RealtimeRuntime = Int64(v.GetValue())
}
if v := cpu.GetRealtimePeriod(); v != nil {
if err := r.owners.claimCpuRealtimePeriod(id, plugin); err != nil {
return err
}
container.Cpu.RealtimePeriod = UInt64(v.GetValue())
reply.Cpu.RealtimePeriod = UInt64(v.GetValue())
}
if v := cpu.GetCpus(); v != "" {
if err := r.owners.claimCpusetCpus(id, plugin); err != nil {
return err
}
container.Cpu.Cpus = v
reply.Cpu.Cpus = v
}
if v := cpu.GetMems(); v != "" {
if err := r.owners.claimCpusetMems(id, plugin); err != nil {
return err
}
container.Cpu.Mems = v
reply.Cpu.Mems = v
}
}
for _, l := range resources.HugepageLimits {
if err := r.owners.claimHugepageLimit(id, l.PageSize, plugin); err != nil {
return err
}
container.HugepageLimits = append(container.HugepageLimits, l)
reply.HugepageLimits = append(reply.HugepageLimits, l)
}
if len(resources.Unified) != 0 {
for k, v := range resources.Unified {
if err := r.owners.claimUnified(id, k, plugin); err != nil {
return err
}
container.Unified[k] = v
reply.Unified[k] = v
}
}
if v := resources.GetBlockioClass(); v != nil {
if err := r.owners.claimBlockioClass(id, plugin); err != nil {
return err
}
container.BlockioClass = String(v.GetValue())
reply.BlockioClass = String(v.GetValue())
}
if v := resources.GetRdtClass(); v != nil {
if err := r.owners.claimRdtClass(id, plugin); err != nil {
return err
}
container.RdtClass = String(v.GetValue())
reply.RdtClass = String(v.GetValue())
}
return nil
}
func (r *result) adjustCgroupsPath(path, plugin string) error {
if path == "" {
return nil
}
create, id := r.request.create, r.request.create.Container.Id
if err := r.owners.claimCgroupsPath(id, plugin); err != nil {
return err
}
create.Container.Linux.CgroupsPath = path
r.reply.adjust.Linux.CgroupsPath = path
return nil
}
func (r *result) adjustRlimits(rlimits []*POSIXRlimit, plugin string) error {
create, id, adjust := r.request.create, r.request.create.Container.Id, r.reply.adjust
for _, l := range rlimits {
if err := r.owners.claimRlimits(id, l.Type, plugin); err != nil {
return err
}
create.Container.Rlimits = append(create.Container.Rlimits, l)
adjust.Rlimits = append(adjust.Rlimits, l)
}
return nil
}
func (r *result) updateResources(reply, u *ContainerUpdate, plugin string) error {
if u.Linux == nil || u.Linux.Resources == nil {
return nil
}
var resources *LinuxResources
request, id := r.request.update, u.ContainerId
// operate on a copy: we won't touch anything on (ignored) failures
if request != nil && request.Container.Id == id {
resources = request.LinuxResources.Copy()
} else {
resources = reply.Linux.Resources.Copy()
}
if mem := u.Linux.Resources.Memory; mem != nil {
if v := mem.GetLimit(); v != nil {
if err := r.owners.claimMemLimit(id, plugin); err != nil {
return err
}
resources.Memory.Limit = Int64(v.GetValue())
}
if v := mem.GetReservation(); v != nil {
if err := r.owners.claimMemReservation(id, plugin); err != nil {
return err
}
resources.Memory.Reservation = Int64(v.GetValue())
}
if v := mem.GetSwap(); v != nil {
if err := r.owners.claimMemSwapLimit(id, plugin); err != nil {
return err
}
resources.Memory.Swap = Int64(v.GetValue())
}
if v := mem.GetKernel(); v != nil {
if err := r.owners.claimMemKernelLimit(id, plugin); err != nil {
return err
}
resources.Memory.Kernel = Int64(v.GetValue())
}
if v := mem.GetKernelTcp(); v != nil {
if err := r.owners.claimMemTCPLimit(id, plugin); err != nil {
return err
}
resources.Memory.KernelTcp = Int64(v.GetValue())
}
if v := mem.GetSwappiness(); v != nil {
if err := r.owners.claimMemSwappiness(id, plugin); err != nil {
return err
}
resources.Memory.Swappiness = UInt64(v.GetValue())
}
if v := mem.GetDisableOomKiller(); v != nil {
if err := r.owners.claimMemDisableOomKiller(id, plugin); err != nil {
return err
}
resources.Memory.DisableOomKiller = Bool(v.GetValue())
}
if v := mem.GetUseHierarchy(); v != nil {
if err := r.owners.claimMemUseHierarchy(id, plugin); err != nil {
return err
}
resources.Memory.UseHierarchy = Bool(v.GetValue())
}
}
if cpu := u.Linux.Resources.Cpu; cpu != nil {
if v := cpu.GetShares(); v != nil {
if err := r.owners.claimCpuShares(id, plugin); err != nil {
return err
}
resources.Cpu.Shares = UInt64(v.GetValue())
}
if v := cpu.GetQuota(); v != nil {
if err := r.owners.claimCpuQuota(id, plugin); err != nil {
return err
}
resources.Cpu.Quota = Int64(v.GetValue())
}
if v := cpu.GetPeriod(); v != nil {
if err := r.owners.claimCpuPeriod(id, plugin); err != nil {
return err
}
resources.Cpu.Period = UInt64(v.GetValue())
}
if v := cpu.GetRealtimeRuntime(); v != nil {
if err := r.owners.claimCpuRealtimeRuntime(id, plugin); err != nil {
return err
}
resources.Cpu.RealtimeRuntime = Int64(v.GetValue())
}
if v := cpu.GetRealtimePeriod(); v != nil {
if err := r.owners.claimCpuRealtimePeriod(id, plugin); err != nil {
return err
}
resources.Cpu.RealtimePeriod = UInt64(v.GetValue())
}
if v := cpu.GetCpus(); v != "" {
if err := r.owners.claimCpusetCpus(id, plugin); err != nil {
return err
}
resources.Cpu.Cpus = v
}
if v := cpu.GetMems(); v != "" {
if err := r.owners.claimCpusetMems(id, plugin); err != nil {
return err
}
resources.Cpu.Mems = v
}
}
for _, l := range u.Linux.Resources.HugepageLimits {
if err := r.owners.claimHugepageLimit(id, l.PageSize, plugin); err != nil {
return err
}
resources.HugepageLimits = append(resources.HugepageLimits, l)
}
if len(u.Linux.Resources.Unified) != 0 {
if resources.Unified == nil {
resources.Unified = make(map[string]string)
}
for k, v := range u.Linux.Resources.Unified {
if err := r.owners.claimUnified(id, k, plugin); err != nil {
return err
}
resources.Unified[k] = v
}
}
if v := u.Linux.Resources.GetBlockioClass(); v != nil {
if err := r.owners.claimBlockioClass(id, plugin); err != nil {
return err
}
resources.BlockioClass = String(v.GetValue())
}
if v := u.Linux.Resources.GetRdtClass(); v != nil {
if err := r.owners.claimRdtClass(id, plugin); err != nil {
return err
}
resources.RdtClass = String(v.GetValue())
}
// update request/reply from copy on success
reply.Linux.Resources = resources.Copy()
if request != nil && request.Container.Id == id {
request.LinuxResources = resources.Copy()
}
return nil
}
func (r *result) getContainerUpdate(u *ContainerUpdate, plugin string) (*ContainerUpdate, error) {
id := u.ContainerId
if r.request.create != nil && r.request.create.Container != nil {
if r.request.create.Container.Id == id {
return nil, fmt.Errorf("plugin %q asked update of %q during creation",
plugin, id)
}
}
if update, ok := r.updates[id]; ok {
update.IgnoreFailure = update.IgnoreFailure && u.IgnoreFailure
return update, nil
}
update := &ContainerUpdate{
ContainerId: id,
Linux: &LinuxContainerUpdate{
Resources: &LinuxResources{
Memory: &LinuxMemory{},
Cpu: &LinuxCPU{},
HugepageLimits: []*HugepageLimit{},
Unified: map[string]string{},
},
},
IgnoreFailure: u.IgnoreFailure,
}
r.updates[id] = update
// for update requests delay appending the requested container (in the response getter)
if r.request.update == nil || r.request.update.Container.Id != id {
r.reply.update = append(r.reply.update, update)
}
return update, nil
}
type owners struct {
annotations map[string]string
mounts map[string]string
devices map[string]string
env map[string]string
memLimit string
memReservation string
memSwapLimit string
memKernelLimit string
memTCPLimit string
memSwappiness string
memDisableOomKiller string
memUseHierarchy string
cpuShares string
cpuQuota string
cpuPeriod string
cpuRealtimeRuntime string
cpuRealtimePeriod string
cpusetCpus string
cpusetMems string
hugepageLimits map[string]string
blockioClass string
rdtClass string
unified map[string]string
cgroupsPath string
rlimits map[string]string
}
func (ro resultOwners) ownersFor(id string) *owners {
o, ok := ro[id]
if !ok {
o = &owners{}
ro[id] = o
}
return o
}
func (ro resultOwners) claimAnnotation(id, key, plugin string) error {
return ro.ownersFor(id).claimAnnotation(key, plugin)
}
func (ro resultOwners) claimMount(id, destination, plugin string) error {
return ro.ownersFor(id).claimMount(destination, plugin)
}
func (ro resultOwners) claimDevice(id, path, plugin string) error {
return ro.ownersFor(id).claimDevice(path, plugin)
}
func (ro resultOwners) claimEnv(id, name, plugin string) error {
return ro.ownersFor(id).claimEnv(name, plugin)
}
func (ro resultOwners) claimMemLimit(id, plugin string) error {
return ro.ownersFor(id).claimMemLimit(plugin)
}
func (ro resultOwners) claimMemReservation(id, plugin string) error {
return ro.ownersFor(id).claimMemReservation(plugin)
}
func (ro resultOwners) claimMemSwapLimit(id, plugin string) error {
return ro.ownersFor(id).claimMemSwapLimit(plugin)
}
func (ro resultOwners) claimMemKernelLimit(id, plugin string) error {
return ro.ownersFor(id).claimMemKernelLimit(plugin)
}
func (ro resultOwners) claimMemTCPLimit(id, plugin string) error {
return ro.ownersFor(id).claimMemTCPLimit(plugin)
}
func (ro resultOwners) claimMemSwappiness(id, plugin string) error {
return ro.ownersFor(id).claimMemSwappiness(plugin)
}
func (ro resultOwners) claimMemDisableOomKiller(id, plugin string) error {
return ro.ownersFor(id).claimMemDisableOomKiller(plugin)
}
func (ro resultOwners) claimMemUseHierarchy(id, plugin string) error {
return ro.ownersFor(id).claimMemUseHierarchy(plugin)
}
func (ro resultOwners) claimCpuShares(id, plugin string) error {
return ro.ownersFor(id).claimCpuShares(plugin)
}
func (ro resultOwners) claimCpuQuota(id, plugin string) error {
return ro.ownersFor(id).claimCpuQuota(plugin)
}
func (ro resultOwners) claimCpuPeriod(id, plugin string) error {
return ro.ownersFor(id).claimCpuPeriod(plugin)
}
func (ro resultOwners) claimCpuRealtimeRuntime(id, plugin string) error {
return ro.ownersFor(id).claimCpuRealtimeRuntime(plugin)
}
func (ro resultOwners) claimCpuRealtimePeriod(id, plugin string) error {
return ro.ownersFor(id).claimCpuRealtimePeriod(plugin)
}
func (ro resultOwners) claimCpusetCpus(id, plugin string) error {
return ro.ownersFor(id).claimCpusetCpus(plugin)
}
func (ro resultOwners) claimCpusetMems(id, plugin string) error {
return ro.ownersFor(id).claimCpusetMems(plugin)
}
func (ro resultOwners) claimHugepageLimit(id, size, plugin string) error {
return ro.ownersFor(id).claimHugepageLimit(size, plugin)
}
func (ro resultOwners) claimBlockioClass(id, plugin string) error {
return ro.ownersFor(id).claimBlockioClass(plugin)
}
func (ro resultOwners) claimRdtClass(id, plugin string) error {
return ro.ownersFor(id).claimRdtClass(plugin)
}
func (ro resultOwners) claimUnified(id, key, plugin string) error {
return ro.ownersFor(id).claimUnified(key, plugin)
}
func (ro resultOwners) claimCgroupsPath(id, plugin string) error {
return ro.ownersFor(id).claimCgroupsPath(plugin)
}
func (ro resultOwners) claimRlimits(id, typ, plugin string) error {
return ro.ownersFor(id).claimRlimit(typ, plugin)
}
func (o *owners) claimAnnotation(key, plugin string) error {
if o.annotations == nil {
o.annotations = make(map[string]string)
}
if other, taken := o.annotations[key]; taken {
return conflict(plugin, other, "annotation", key)
}
o.annotations[key] = plugin
return nil
}
func (o *owners) claimMount(destination, plugin string) error {
if o.mounts == nil {
o.mounts = make(map[string]string)
}
if other, taken := o.mounts[destination]; taken {
return conflict(plugin, other, "mount", destination)
}
o.mounts[destination] = plugin
return nil
}
func (o *owners) claimDevice(path, plugin string) error {
if o.devices == nil {
o.devices = make(map[string]string)
}
if other, taken := o.devices[path]; taken {
return conflict(plugin, other, "device", path)
}
o.devices[path] = plugin
return nil
}
func (o *owners) claimEnv(name, plugin string) error {
if o.env == nil {
o.env = make(map[string]string)
}
if other, taken := o.env[name]; taken {
return conflict(plugin, other, "env", name)
}
o.env[name] = plugin
return nil
}
func (o *owners) claimMemLimit(plugin string) error {
if other := o.memLimit; other != "" {
return conflict(plugin, other, "memory limit")
}
o.memLimit = plugin
return nil
}
func (o *owners) claimMemReservation(plugin string) error {
if other := o.memReservation; other != "" {
return conflict(plugin, other, "memory reservation")
}
o.memReservation = plugin
return nil
}
func (o *owners) claimMemSwapLimit(plugin string) error {
if other := o.memSwapLimit; other != "" {
return conflict(plugin, other, "memory swap limit")
}
o.memSwapLimit = plugin
return nil
}
func (o *owners) claimMemKernelLimit(plugin string) error {
if other := o.memKernelLimit; other != "" {
return conflict(plugin, other, "memory kernel limit")
}
o.memKernelLimit = plugin
return nil
}
func (o *owners) claimMemTCPLimit(plugin string) error {
if other := o.memTCPLimit; other != "" {
return conflict(plugin, other, "memory TCP limit")
}
o.memTCPLimit = plugin
return nil
}
func (o *owners) claimMemSwappiness(plugin string) error {
if other := o.memSwappiness; other != "" {
return conflict(plugin, other, "memory swappiness")
}
o.memSwappiness = plugin
return nil
}
func (o *owners) claimMemDisableOomKiller(plugin string) error {
if other := o.memDisableOomKiller; other != "" {
return conflict(plugin, other, "memory disable OOM killer")
}
o.memDisableOomKiller = plugin
return nil
}
func (o *owners) claimMemUseHierarchy(plugin string) error {
if other := o.memUseHierarchy; other != "" {
return conflict(plugin, other, "memory 'UseHierarchy'")
}
o.memUseHierarchy = plugin
return nil
}
func (o *owners) claimCpuShares(plugin string) error {
if other := o.cpuShares; other != "" {
return conflict(plugin, other, "CPU shares")
}
o.cpuShares = plugin
return nil
}
func (o *owners) claimCpuQuota(plugin string) error {
if other := o.cpuQuota; other != "" {
return conflict(plugin, other, "CPU quota")
}
o.cpuQuota = plugin
return nil
}
func (o *owners) claimCpuPeriod(plugin string) error {
if other := o.cpuPeriod; other != "" {
return conflict(plugin, other, "CPU period")
}
o.cpuPeriod = plugin
return nil
}
func (o *owners) claimCpuRealtimeRuntime(plugin string) error {
if other := o.cpuRealtimeRuntime; other != "" {
return conflict(plugin, other, "CPU realtime runtime")
}
o.cpuRealtimeRuntime = plugin
return nil
}
func (o *owners) claimCpuRealtimePeriod(plugin string) error {
if other := o.cpuRealtimePeriod; other != "" {
return conflict(plugin, other, "CPU realtime period")
}
o.cpuRealtimePeriod = plugin
return nil
}
func (o *owners) claimCpusetCpus(plugin string) error {
if other := o.cpusetCpus; other != "" {
return conflict(plugin, other, "CPU pinning")
}
o.cpusetCpus = plugin
return nil
}
func (o *owners) claimCpusetMems(plugin string) error {
if other := o.cpusetMems; other != "" {
return conflict(plugin, other, "memory pinning")
}
o.cpusetMems = plugin
return nil
}
func (o *owners) claimHugepageLimit(size, plugin string) error {
if o.hugepageLimits == nil {
o.hugepageLimits = make(map[string]string)
}
if other, taken := o.hugepageLimits[size]; taken {
return conflict(plugin, other, "hugepage limit of size", size)
}
o.hugepageLimits[size] = plugin
return nil
}
func (o *owners) claimBlockioClass(plugin string) error {
if other := o.blockioClass; other != "" {
return conflict(plugin, other, "block I/O class")
}
o.blockioClass = plugin
return nil
}
func (o *owners) claimRdtClass(plugin string) error {
if other := o.rdtClass; other != "" {
return conflict(plugin, other, "RDT class")
}
o.rdtClass = plugin
return nil
}
func (o *owners) claimUnified(key, plugin string) error {
if o.unified == nil {
o.unified = make(map[string]string)
}
if other, taken := o.unified[key]; taken {
return conflict(plugin, other, "unified resource", key)
}
o.unified[key] = plugin
return nil
}
func (o *owners) claimRlimit(typ, plugin string) error {
if o.rlimits == nil {
o.rlimits = make(map[string]string)
}
if other, taken := o.rlimits[typ]; taken {
return conflict(plugin, other, "rlimit", typ)
}
o.rlimits[typ] = plugin
return nil
}
func (o *owners) claimCgroupsPath(plugin string) error {
if other := o.cgroupsPath; other != "" {
return conflict(plugin, other, "cgroups path")
}
o.cgroupsPath = plugin
return nil
}
func (ro resultOwners) clearAnnotation(id, key string) {
ro.ownersFor(id).clearAnnotation(key)
}
func (ro resultOwners) clearMount(id, destination string) {
ro.ownersFor(id).clearMount(destination)
}
func (ro resultOwners) clearDevice(id, path string) {
ro.ownersFor(id).clearDevice(path)
}
func (ro resultOwners) clearEnv(id, name string) {
ro.ownersFor(id).clearEnv(name)
}
func (o *owners) clearAnnotation(key string) {
if o.annotations == nil {
return
}
delete(o.annotations, key)
}
func (o *owners) clearMount(destination string) {
if o.mounts == nil {
return
}
delete(o.mounts, destination)
}
func (o *owners) clearDevice(path string) {
if o.devices == nil {
return
}
delete(o.devices, path)
}
func (o *owners) clearEnv(name string) {
if o.env == nil {
return
}
delete(o.env, name)
}
func conflict(plugin, other, subject string, qualif ...string) error {
return fmt.Errorf("plugins %q and %q both tried to set %s",
plugin, other, strings.Join(append([]string{subject}, qualif...), " "))
}
nri-0.6.1/pkg/adaptation/suite_test.go 0000664 0000000 0000000 00000041745 14610311645 0017746 0 ustar 00root root 0000000 0000000 /*
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 adaptation_test
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
"sort"
"sync"
"testing"
"time"
nri "github.com/containerd/nri/pkg/adaptation"
"github.com/containerd/nri/pkg/api"
"github.com/sirupsen/logrus"
"github.com/containerd/nri/pkg/stub"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestRuntime(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "NRI Runtime")
}
const (
startupTimeout = 2 * time.Second
)
// A test suite consist of a runtime and a set of plugins.
type Suite struct {
dir string // directory to create for test
runtime *mockRuntime // runtime instance for test
plugins []*mockPlugin // plugin intances for test
}
// SuiteOption can be applied to a suite.
type SuiteOption func(s *Suite) error
// Prepare test suite, creating test directory.
func (s *Suite) Prepare(runtime *mockRuntime, plugins ...*mockPlugin) string {
var (
dir string
etc string
)
logrus.SetLevel(logrus.ErrorLevel)
dir = GinkgoT().TempDir()
etc = filepath.Join(dir, "etc", "nri")
Expect(os.MkdirAll(etc, 0o755)).To(Succeed())
s.dir = dir
s.runtime = runtime
s.plugins = plugins
return dir
}
// Dir returns the suite's temporary test directory.
func (s *Suite) Dir() string {
return s.dir
}
// Startup starts up the test suite.
func (s *Suite) Startup() {
s.StartRuntime()
s.StartPlugins()
s.WaitForPluginsToSync()
}
// StartRuntime starts the suite runtime.
func (s *Suite) StartRuntime() {
Expect(s.runtime.Start(s.dir)).To(Succeed())
}
// StartPlugins starts the suite plugins.
func (s *Suite) StartPlugins() {
for _, plugin := range s.plugins {
Expect(plugin.Start(s.dir)).To(Succeed())
}
}
// WaitForPluginsToSync waits for the suite plugins to get synchronized.
func (s *Suite) WaitForPluginsToSync() {
timeout := time.After(startupTimeout)
for _, plugin := range s.plugins {
Expect(plugin.Wait(PluginSynchronized, timeout)).To(Succeed())
}
}
// Cleanup the test suite.
func (s *Suite) Cleanup() {
s.runtime.Stop()
// TODO(klihub):
for _, plugin := range s.plugins {
plugin.Stop()
}
Expect(os.RemoveAll(s.dir)).To(Succeed())
}
// ------------------------------------
func Log(format string, args ...interface{}) {
GinkgoWriter.Printf(format+"\n", args...)
}
type mockRuntime struct {
options []nri.Option
runtime *nri.Adaptation
pods map[string]*api.PodSandbox
ctrs map[string]*api.Container
updateFn nri.UpdateFn
}
func (m *mockRuntime) Start(dir string) error {
var (
options = []nri.Option{
nri.WithPluginPath(filepath.Join(dir, "opt", "nri", "plugins")),
nri.WithPluginConfigPath(filepath.Join(dir, "etc", "nri", "conf.d")),
nri.WithSocketPath(filepath.Join(dir, "nri.sock")),
}
err error
)
if m.runtime != nil {
return errors.New("mock runtime already started")
}
options = append(options, m.options...)
m.runtime, err = nri.New("mockRuntime", "0.0.1", m.synchronize, m.update, options...)
if err != nil {
return err
}
if m.pods == nil {
m.pods = make(map[string]*api.PodSandbox)
}
if m.ctrs == nil {
m.ctrs = make(map[string]*api.Container)
}
if m.updateFn == nil {
m.updateFn = func(context.Context, []*api.ContainerUpdate) ([]*api.ContainerUpdate, error) {
return nil, nil
}
}
return m.runtime.Start()
}
func (m *mockRuntime) Stop() {
if m.runtime != nil {
m.runtime.Stop()
m.runtime = nil
}
}
func (m *mockRuntime) synchronize(ctx context.Context, cb nri.SyncCB) error {
var (
pods []*api.PodSandbox
ctrs []*api.Container
ids []string
)
for id := range m.pods {
ids = append(ids, id)
}
sort.Strings(ids)
for _, id := range ids {
pods = append(pods, m.pods[id])
}
ids = nil
for id := range m.ctrs {
ids = append(ids, id)
}
sort.Strings(ids)
for _, id := range ids {
ctrs = append(ctrs, m.ctrs[id])
}
_, err := cb(ctx, pods, ctrs)
return err
}
func (m *mockRuntime) startStopPodAndContainer(ctx context.Context, pod *api.PodSandbox, ctr *api.Container) error {
err := m.runtime.RunPodSandbox(ctx, &api.StateChangeEvent{
Pod: pod,
})
if err != nil {
return err
}
_, err = m.runtime.CreateContainer(ctx, &api.CreateContainerRequest{
Pod: pod,
Container: ctr,
})
if err != nil {
return err
}
err = m.runtime.PostCreateContainer(ctx, &api.StateChangeEvent{
Pod: pod,
Container: ctr,
})
if err != nil {
return err
}
err = m.runtime.StartContainer(ctx, &api.StateChangeEvent{
Pod: pod,
Container: ctr,
})
if err != nil {
return err
}
err = m.runtime.PostStartContainer(ctx, &api.StateChangeEvent{
Pod: pod,
Container: ctr,
})
if err != nil {
return err
}
_, err = m.runtime.UpdateContainer(ctx, &api.UpdateContainerRequest{
Pod: pod,
Container: ctr,
LinuxResources: &api.LinuxResources{},
})
if err != nil {
return err
}
err = m.runtime.PostUpdateContainer(ctx, &api.StateChangeEvent{
Pod: pod,
Container: ctr,
})
if err != nil {
return err
}
_, err = m.runtime.StopContainer(ctx, &api.StopContainerRequest{
Pod: pod,
Container: ctr,
})
if err != nil {
return err
}
err = m.runtime.RemoveContainer(ctx, &api.StateChangeEvent{
Pod: pod,
Container: ctr,
})
if err != nil {
return err
}
err = m.runtime.StopPodSandbox(ctx, &api.StateChangeEvent{
Pod: pod,
})
if err != nil {
return err
}
err = m.runtime.RemovePodSandbox(ctx, &api.StateChangeEvent{
Pod: pod,
})
if err != nil {
return err
}
return nil
}
func (m *mockRuntime) update(ctx context.Context, updates []*nri.ContainerUpdate) ([]*nri.ContainerUpdate, error) {
return m.updateFn(ctx, updates)
}
type mockPlugin struct {
name string
idx string
stub stub.Stub
mask stub.EventMask
q *EventQ
pods map[string]*api.PodSandbox
ctrs map[string]*api.Container
runPodSandbox func(*mockPlugin, *api.PodSandbox, *api.Container) error
stopPodSandbox func(*mockPlugin, *api.PodSandbox, *api.Container) error
removePodSandbox func(*mockPlugin, *api.PodSandbox, *api.Container) error
createContainer func(*mockPlugin, *api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error)
postCreateContainer func(*mockPlugin, *api.PodSandbox, *api.Container) error
startContainer func(*mockPlugin, *api.PodSandbox, *api.Container) error
postStartContainer func(*mockPlugin, *api.PodSandbox, *api.Container) error
updateContainer func(*mockPlugin, *api.PodSandbox, *api.Container, *api.LinuxResources) ([]*api.ContainerUpdate, error)
postUpdateContainer func(*mockPlugin, *api.PodSandbox, *api.Container) error
stopContainer func(*mockPlugin, *api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
removeContainer func(*mockPlugin, *api.PodSandbox, *api.Container) error
}
var (
_ = stub.ConfigureInterface(&mockPlugin{})
_ = stub.SynchronizeInterface(&mockPlugin{})
_ = stub.RunPodInterface(&mockPlugin{})
_ = stub.StopPodInterface(&mockPlugin{})
_ = stub.RemovePodInterface(&mockPlugin{})
_ = stub.CreateContainerInterface(&mockPlugin{})
_ = stub.StartContainerInterface(&mockPlugin{})
_ = stub.UpdateContainerInterface(&mockPlugin{})
_ = stub.StopContainerInterface(&mockPlugin{})
_ = stub.RemoveContainerInterface(&mockPlugin{})
_ = stub.PostCreateContainerInterface(&mockPlugin{})
_ = stub.PostStartContainerInterface(&mockPlugin{})
_ = stub.PostUpdateContainerInterface(&mockPlugin{})
)
func (m *mockPlugin) Log(format string, args ...interface{}) {
Log("* [plugin %s-%s] "+format, append([]interface{}{m.idx, m.name}, args...)...)
}
func (m *mockPlugin) SetFallbackName(name string, idx int) {
if m.name == "" {
m.name = name
}
if m.idx == "" {
m.idx = fmt.Sprintf("%02d", idx)
}
}
func (m *mockPlugin) Wait(e *Event, deadline <-chan time.Time) error {
_, err := m.q.Wait(e, deadline)
return err
}
func (m *mockPlugin) Events() []*Event {
return m.q.Events()
}
func (m *mockPlugin) EventQ() *EventQ {
return m.q
}
func (m *mockPlugin) Init(dir string) error {
var err error
if m.stub != nil {
return fmt.Errorf("plugin %s-%s already initialized", m.idx, m.name)
}
if m.name == "" {
m.name = "mock-plugin"
}
if m.idx == "" {
m.idx = "00"
}
if m.mask == 0 {
m.mask = api.ValidEvents
}
m.q = &EventQ{}
m.Log("Init()...")
m.stub, err = stub.New(m,
stub.WithPluginName(m.name),
stub.WithPluginIdx(m.idx),
stub.WithSocketPath(filepath.Join(dir, "nri.sock")),
stub.WithOnClose(m.onClose),
)
if err != nil {
m.q.Add(PluginCreationError)
return err
}
m.pods = make(map[string]*api.PodSandbox)
m.ctrs = make(map[string]*api.Container)
if m.runPodSandbox == nil {
m.runPodSandbox = nopEvent
}
if m.stopPodSandbox == nil {
m.stopPodSandbox = nopEvent
}
if m.removePodSandbox == nil {
m.removePodSandbox = nopEvent
}
if m.createContainer == nil {
m.createContainer = nopCreateContainer
}
if m.postCreateContainer == nil {
m.postCreateContainer = nopEvent
}
if m.startContainer == nil {
m.startContainer = nopEvent
}
if m.postStartContainer == nil {
m.postStartContainer = nopEvent
}
if m.updateContainer == nil {
m.updateContainer = nopUpdateContainer
}
if m.postUpdateContainer == nil {
m.postUpdateContainer = nopEvent
}
if m.stopContainer == nil {
m.stopContainer = nopStopContainer
}
if m.removeContainer == nil {
m.removeContainer = nopEvent
}
return nil
}
func (m *mockPlugin) Start(dir string) error {
if m.stub == nil {
if err := m.Init(dir); err != nil {
return err
}
}
if err := m.stub.Start(context.Background()); err != nil {
m.q.Add(PluginStartupError)
return err
}
return nil
}
func (m *mockPlugin) Stop() {
if m.stub != nil {
m.stub.Stop()
m.stub.Wait()
}
m.q.Add(PluginStopped)
}
func (m *mockPlugin) onClose() {
if m.stub != nil {
m.stub.Stop()
m.stub.Wait()
}
if m.q != nil {
m.q.Add(PluginDisconnected)
}
}
func (m *mockPlugin) Configure(_ context.Context, cfg, runtime, version string) (stub.EventMask, error) {
m.q.Add(PluginConfigured)
return m.mask, nil
}
func (m *mockPlugin) Synchronize(_ context.Context, pods []*api.PodSandbox, ctrs []*api.Container) ([]*api.ContainerUpdate, error) {
for _, pod := range pods {
m.pods[pod.Id] = pod
}
for _, ctr := range ctrs {
m.ctrs[ctr.Id] = ctr
}
m.q.Add(PluginSynchronized)
return nil, nil
}
func (m *mockPlugin) Shutdown(_ context.Context) {
m.q.Add(PluginShutdown)
}
func (m *mockPlugin) RunPodSandbox(_ context.Context, pod *api.PodSandbox) error {
m.pods[pod.Id] = pod
err := m.runPodSandbox(m, pod, nil)
m.q.Add(PodSandboxEvent(pod, RunPodSandbox))
return err
}
func (m *mockPlugin) StopPodSandbox(_ context.Context, pod *api.PodSandbox) error {
m.pods[pod.Id] = pod
err := m.stopPodSandbox(m, pod, nil)
m.q.Add(PodSandboxEvent(pod, StopPodSandbox))
return err
}
func (m *mockPlugin) RemovePodSandbox(_ context.Context, pod *api.PodSandbox) error {
delete(m.pods, pod.Id)
err := m.removePodSandbox(m, pod, nil)
m.q.Add(PodSandboxEvent(pod, RemovePodSandbox))
return err
}
func (m *mockPlugin) CreateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
m.pods[pod.Id] = pod
m.ctrs[ctr.Id] = ctr
m.q.Add(ContainerEvent(ctr, CreateContainer))
return m.createContainer(m, pod, ctr)
}
func (m *mockPlugin) PostCreateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
m.pods[pod.Id] = pod
m.ctrs[ctr.Id] = ctr
m.q.Add(ContainerEvent(ctr, PostCreateContainer))
return m.postCreateContainer(m, pod, ctr)
}
func (m *mockPlugin) StartContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
m.pods[pod.Id] = pod
m.ctrs[ctr.Id] = ctr
m.q.Add(ContainerEvent(ctr, StartContainer))
return m.startContainer(m, pod, ctr)
}
func (m *mockPlugin) PostStartContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
m.pods[pod.Id] = pod
m.ctrs[ctr.Id] = ctr
m.q.Add(ContainerEvent(ctr, PostStartContainer))
return m.postStartContainer(m, pod, ctr)
}
func (m *mockPlugin) UpdateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container, res *api.LinuxResources) ([]*api.ContainerUpdate, error) {
m.pods[pod.Id] = pod
m.ctrs[ctr.Id] = ctr
m.q.Add(ContainerEvent(ctr, UpdateContainer))
return m.updateContainer(m, pod, ctr, res)
}
func (m *mockPlugin) PostUpdateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
m.pods[pod.Id] = pod
m.ctrs[ctr.Id] = ctr
m.q.Add(ContainerEvent(ctr, PostUpdateContainer))
return m.postUpdateContainer(m, pod, ctr)
}
func (m *mockPlugin) StopContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
m.pods[pod.Id] = pod
m.ctrs[ctr.Id] = ctr
m.q.Add(ContainerEvent(ctr, StopContainer))
return m.stopContainer(m, pod, ctr)
}
func (m *mockPlugin) RemoveContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
delete(m.ctrs, ctr.Id)
m.q.Add(ContainerEvent(ctr, RemoveContainer))
return m.removeContainer(m, pod, ctr)
}
func nopEvent(*mockPlugin, *api.PodSandbox, *api.Container) error {
return nil
}
func nopCreateContainer(*mockPlugin, *api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
return nil, nil, nil
}
func nopUpdateContainer(*mockPlugin, *api.PodSandbox, *api.Container, *api.LinuxResources) ([]*api.ContainerUpdate, error) {
return nil, nil
}
func nopStopContainer(*mockPlugin, *api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error) {
return nil, nil
}
type EventType string
const (
CreateError = "create-error"
Started = "started"
Configured = "configured"
Synchronized = "synchronized"
StartupError = "startup-error"
Shutdown = "shutdown"
Disconnected = "closed"
Stopped = "stopped"
RunPodSandbox = "RunPodSandbox"
StopPodSandbox = "StopPodSandbox"
RemovePodSandbox = "RemovePodSandbox"
CreateContainer = "CreateContainer"
StartContainer = "StartContainer"
UpdateContainer = "UpdateContainer"
StopContainer = "StopContainer"
RemoveContainer = "RemoveContainer"
PostCreateContainer = "PostCreateContainer"
PostStartContainer = "PostStartContainer"
PostUpdateContainer = "PostUpdateContainer"
Error = "Error"
Timeout = ""
)
type Event struct {
Type EventType
Pod *api.PodSandbox
Ctr *api.Container
}
var (
PluginCreationError = &Event{Type: CreateError}
PluginConfigured = &Event{Type: Configured}
PluginSynchronized = &Event{Type: Synchronized}
PluginStartupError = &Event{Type: StartupError}
PluginShutdown = &Event{Type: Shutdown}
PluginDisconnected = &Event{Type: Disconnected}
PluginStopped = &Event{Type: Stopped}
PodSandboxEvent = func(pod *api.PodSandbox, t EventType) *Event {
return &Event{Type: t, Pod: pod}
}
ContainerEvent = func(ctr *api.Container, t EventType) *Event {
return &Event{Type: t, Ctr: ctr}
}
)
func (e *Event) Matches(o *Event) bool {
if e.Type != o.Type {
return false
}
if e.Pod != nil && o.Pod != nil {
if e.Pod.Id != o.Pod.Id {
return false
}
}
if e.Ctr != nil && o.Ctr != nil {
if e.Ctr.Id != o.Ctr.Id || e.Ctr.PodSandboxId != o.Ctr.PodSandboxId {
return false
}
}
return true
}
func (e *Event) String() string {
str := ""
switch {
case e.Ctr != nil:
str += e.Ctr.PodSandboxId + ":" + e.Ctr.Id + "/"
case e.Pod != nil:
str += e.Pod.Id + "/"
}
return str + string(e.Type)
}
type EventQ struct {
sync.Mutex
q []*Event
c chan *Event
}
func (q *EventQ) Add(e *Event) {
if q == nil {
return
}
q.Lock()
defer q.Unlock()
q.q = append(q.q, e)
if q.c != nil {
q.c <- e
}
}
func (q *EventQ) Reset(e *Event) {
q.Lock()
defer q.Unlock()
q.q = []*Event{}
}
func (q *EventQ) Events() []*Event {
q.Lock()
defer q.Unlock()
var events []*Event
events = append(events, q.q...)
return events
}
func (q *EventQ) Has(e *Event) bool {
q.Lock()
defer q.Unlock()
return q.search(e) != nil
}
func (q *EventQ) search(e *Event) *Event {
for _, qe := range q.q {
if qe.Matches(e) {
return qe
}
}
return nil
}
func (q *EventQ) Wait(w *Event, deadline <-chan time.Time) (*Event, error) {
var unlocked bool
q.Lock()
defer func() {
if !unlocked {
q.Unlock()
}
}()
if e := q.search(w); e != nil {
return e, nil
}
if q.c != nil {
return nil, errors.New("event queue already busy Wait()ing")
}
q.c = make(chan *Event, 16)
defer func() {
c := q.c
q.c = nil
close(c)
}()
q.Unlock()
unlocked = true
for {
select {
case e := <-q.c:
if e.Matches(w) {
return e, nil
}
case <-deadline:
return nil, fmt.Errorf("event queue timed out Wait()ing for %s", w)
}
}
}
nri-0.6.1/pkg/api/ 0000775 0000000 0000000 00000000000 14610311645 0013641 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/api/adjustment.go 0000664 0000000 0000000 00000024415 14610311645 0016354 0 ustar 00root root 0000000 0000000 /*
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 api
//
// Notes:
// Adjustment of metadata that is stored in maps (labels and annotations)
// currently assumes that a single plugin will never do an add prior to a
// delete for any key. IOW, it is always assumed that if both a deletion
// and an addition/setting was recorded for a key then the final desired
// state is the addition. This seems like a reasonably safe assumption. A
// removal is usually done only to protect against triggering the conflict
// in the runtime when a plugin intends to touch a key which is known to
// have been put there or already modified by another plugin.
//
// An alternative without this implicit ordering assumption would be to
// store the adjustment for such data as a sequence of add/del operations
// in a slice. At the moment that does not seem to be necessary.
//
// AddAnnotation records the addition of the annotation key=value.
func (a *ContainerAdjustment) AddAnnotation(key, value string) {
a.initAnnotations()
a.Annotations[key] = value
}
// RemoveAnnotation records the removal of the annotation for the given key.
// Normally it is an error for a plugin to try and alter an annotation
// touched by another plugin. However, this is not an error if the plugin
// removes that annotation prior to touching it.
func (a *ContainerAdjustment) RemoveAnnotation(key string) {
a.initAnnotations()
a.Annotations[MarkForRemoval(key)] = ""
}
// AddMount records the addition of a mount to a container.
func (a *ContainerAdjustment) AddMount(m *Mount) {
a.Mounts = append(a.Mounts, m) // TODO: should we dup m here ?
}
// RemoveMount records the removal of a mount from a container.
// Normally it is an error for a plugin to try and alter a mount
// touched by another plugin. However, this is not an error if the
// plugin removes that mount prior to touching it.
func (a *ContainerAdjustment) RemoveMount(ContainerPath string) {
a.Mounts = append(a.Mounts, &Mount{
Destination: MarkForRemoval(ContainerPath),
})
}
// AddEnv records the addition of an environment variable to a container.
func (a *ContainerAdjustment) AddEnv(key, value string) {
a.Env = append(a.Env, &KeyValue{
Key: key,
Value: value,
})
}
// RemoveEnv records the removal of an environment variable from a container.
// Normally it is an error for a plugin to try and alter an environment
// variable touched by another container. However, this is not an error if
// the plugin removes that variable prior to touching it.
func (a *ContainerAdjustment) RemoveEnv(key string) {
a.Env = append(a.Env, &KeyValue{
Key: MarkForRemoval(key),
})
}
// AddHooks records the addition of the given hooks to a container.
func (a *ContainerAdjustment) AddHooks(h *Hooks) {
a.initHooks()
if h.Prestart != nil {
a.Hooks.Prestart = append(a.Hooks.Prestart, h.Prestart...)
}
if h.CreateRuntime != nil {
a.Hooks.CreateRuntime = append(a.Hooks.CreateRuntime, h.CreateRuntime...)
}
if h.CreateContainer != nil {
a.Hooks.CreateContainer = append(a.Hooks.CreateContainer, h.CreateContainer...)
}
if h.StartContainer != nil {
a.Hooks.StartContainer = append(a.Hooks.StartContainer, h.StartContainer...)
}
if h.Poststart != nil {
a.Hooks.Poststart = append(a.Hooks.Poststart, h.Poststart...)
}
if h.Poststop != nil {
a.Hooks.Poststop = append(a.Hooks.Poststop, h.Poststop...)
}
}
func (a *ContainerAdjustment) AddRlimit(typ string, hard, soft uint64) {
a.initRlimits()
a.Rlimits = append(a.Rlimits, &POSIXRlimit{
Type: typ,
Hard: hard,
Soft: soft,
})
}
// AddDevice records the addition of the given device to a container.
func (a *ContainerAdjustment) AddDevice(d *LinuxDevice) {
a.initLinux()
a.Linux.Devices = append(a.Linux.Devices, d) // TODO: should we dup d here ?
}
// RemoveDevice records the removal of a device from a container.
// Normally it is an error for a plugin to try and alter an device
// touched by another container. However, this is not an error if
// the plugin removes that device prior to touching it.
func (a *ContainerAdjustment) RemoveDevice(path string) {
a.initLinux()
a.Linux.Devices = append(a.Linux.Devices, &LinuxDevice{
Path: MarkForRemoval(path),
})
}
// SetLinuxMemoryLimit records setting the memory limit for a container.
func (a *ContainerAdjustment) SetLinuxMemoryLimit(value int64) {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.Limit = Int64(value)
}
// SetLinuxMemoryReservation records setting the memory reservation for a container.
func (a *ContainerAdjustment) SetLinuxMemoryReservation(value int64) {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.Reservation = Int64(value)
}
// SetLinuxMemorySwap records records setting the memory swap limit for a container.
func (a *ContainerAdjustment) SetLinuxMemorySwap(value int64) {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.Swap = Int64(value)
}
// SetLinuxMemoryKernel records setting the memory kernel limit for a container.
func (a *ContainerAdjustment) SetLinuxMemoryKernel(value int64) {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.Kernel = Int64(value)
}
// SetLinuxMemoryKernelTCP records setting the memory kernel TCP limit for a container.
func (a *ContainerAdjustment) SetLinuxMemoryKernelTCP(value int64) {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.KernelTcp = Int64(value)
}
// SetLinuxMemorySwappiness records setting the memory swappiness for a container.
func (a *ContainerAdjustment) SetLinuxMemorySwappiness(value uint64) {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.Swappiness = UInt64(value)
}
// SetLinuxMemoryDisableOomKiller records disabling the OOM killer for a container.
func (a *ContainerAdjustment) SetLinuxMemoryDisableOomKiller() {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.DisableOomKiller = Bool(true)
}
// SetLinuxMemoryUseHierarchy records enabling hierarchical memory accounting for a container.
func (a *ContainerAdjustment) SetLinuxMemoryUseHierarchy() {
a.initLinuxResourcesMemory()
a.Linux.Resources.Memory.UseHierarchy = Bool(true)
}
// SetLinuxCPUShares records setting the scheduler's CPU shares for a container.
func (a *ContainerAdjustment) SetLinuxCPUShares(value uint64) {
a.initLinuxResourcesCPU()
a.Linux.Resources.Cpu.Shares = UInt64(value)
}
// SetLinuxCPUQuota records setting the scheduler's CPU quota for a container.
func (a *ContainerAdjustment) SetLinuxCPUQuota(value int64) {
a.initLinuxResourcesCPU()
a.Linux.Resources.Cpu.Quota = Int64(value)
}
// SetLinuxCPUPeriod records setting the scheduler's CPU period for a container.
func (a *ContainerAdjustment) SetLinuxCPUPeriod(value int64) {
a.initLinuxResourcesCPU()
a.Linux.Resources.Cpu.Period = UInt64(value)
}
// SetLinuxCPURealtimeRuntime records setting the scheduler's realtime runtime for a container.
func (a *ContainerAdjustment) SetLinuxCPURealtimeRuntime(value int64) {
a.initLinuxResourcesCPU()
a.Linux.Resources.Cpu.RealtimeRuntime = Int64(value)
}
// SetLinuxCPURealtimePeriod records setting the scheduler's realtime period for a container.
func (a *ContainerAdjustment) SetLinuxCPURealtimePeriod(value uint64) {
a.initLinuxResourcesCPU()
a.Linux.Resources.Cpu.RealtimePeriod = UInt64(value)
}
// SetLinuxCPUSetCPUs records setting the cpuset CPUs for a container.
func (a *ContainerAdjustment) SetLinuxCPUSetCPUs(value string) {
a.initLinuxResourcesCPU()
a.Linux.Resources.Cpu.Cpus = value
}
// SetLinuxCPUSetMems records setting the cpuset memory for a container.
func (a *ContainerAdjustment) SetLinuxCPUSetMems(value string) {
a.initLinuxResourcesCPU()
a.Linux.Resources.Cpu.Mems = value
}
// AddLinuxHugepageLimit records adding a hugepage limit for a container.
func (a *ContainerAdjustment) AddLinuxHugepageLimit(pageSize string, value uint64) {
a.initLinuxResources()
a.Linux.Resources.HugepageLimits = append(a.Linux.Resources.HugepageLimits,
&HugepageLimit{
PageSize: pageSize,
Limit: value,
})
}
// SetLinuxBlockIOClass records setting the Block I/O class for a container.
func (a *ContainerAdjustment) SetLinuxBlockIOClass(value string) {
a.initLinuxResources()
a.Linux.Resources.BlockioClass = String(value)
}
// SetLinuxRDTClass records setting the RDT class for a container.
func (a *ContainerAdjustment) SetLinuxRDTClass(value string) {
a.initLinuxResources()
a.Linux.Resources.RdtClass = String(value)
}
// AddLinuxUnified sets a cgroupv2 unified resource.
func (a *ContainerAdjustment) AddLinuxUnified(key, value string) {
a.initLinuxResourcesUnified()
a.Linux.Resources.Unified[key] = value
}
// SetLinuxCgroupsPath records setting the cgroups path for a container.
func (a *ContainerAdjustment) SetLinuxCgroupsPath(value string) {
a.initLinux()
a.Linux.CgroupsPath = value
}
//
// Initializing a container adjustment and container update.
//
func (a *ContainerAdjustment) initAnnotations() {
if a.Annotations == nil {
a.Annotations = make(map[string]string)
}
}
func (a *ContainerAdjustment) initHooks() {
if a.Hooks == nil {
a.Hooks = &Hooks{}
}
}
func (a *ContainerAdjustment) initRlimits() {
if a.Rlimits == nil {
a.Rlimits = []*POSIXRlimit{}
}
}
func (a *ContainerAdjustment) initLinux() {
if a.Linux == nil {
a.Linux = &LinuxContainerAdjustment{}
}
}
func (a *ContainerAdjustment) initLinuxResources() {
a.initLinux()
if a.Linux.Resources == nil {
a.Linux.Resources = &LinuxResources{}
}
}
func (a *ContainerAdjustment) initLinuxResourcesMemory() {
a.initLinuxResources()
if a.Linux.Resources.Memory == nil {
a.Linux.Resources.Memory = &LinuxMemory{}
}
}
func (a *ContainerAdjustment) initLinuxResourcesCPU() {
a.initLinuxResources()
if a.Linux.Resources.Cpu == nil {
a.Linux.Resources.Cpu = &LinuxCPU{}
}
}
func (a *ContainerAdjustment) initLinuxResourcesUnified() {
a.initLinuxResources()
if a.Linux.Resources.Unified == nil {
a.Linux.Resources.Unified = make(map[string]string)
}
}
nri-0.6.1/pkg/api/api.pb.go 0000664 0000000 0000000 00000504353 14610311645 0015353 0 ustar 00root root 0000000 0000000 //
//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: pkg/api/api.proto
package api
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)
)
// Events that plugins can subscribe to in ConfigureResponse.
type Event int32
const (
Event_UNKNOWN Event = 0
Event_RUN_POD_SANDBOX Event = 1
Event_STOP_POD_SANDBOX Event = 2
Event_REMOVE_POD_SANDBOX Event = 3
Event_CREATE_CONTAINER Event = 4
Event_POST_CREATE_CONTAINER Event = 5
Event_START_CONTAINER Event = 6
Event_POST_START_CONTAINER Event = 7
Event_UPDATE_CONTAINER Event = 8
Event_POST_UPDATE_CONTAINER Event = 9
Event_STOP_CONTAINER Event = 10
Event_REMOVE_CONTAINER Event = 11
Event_LAST Event = 12
)
// Enum value maps for Event.
var (
Event_name = map[int32]string{
0: "UNKNOWN",
1: "RUN_POD_SANDBOX",
2: "STOP_POD_SANDBOX",
3: "REMOVE_POD_SANDBOX",
4: "CREATE_CONTAINER",
5: "POST_CREATE_CONTAINER",
6: "START_CONTAINER",
7: "POST_START_CONTAINER",
8: "UPDATE_CONTAINER",
9: "POST_UPDATE_CONTAINER",
10: "STOP_CONTAINER",
11: "REMOVE_CONTAINER",
12: "LAST",
}
Event_value = map[string]int32{
"UNKNOWN": 0,
"RUN_POD_SANDBOX": 1,
"STOP_POD_SANDBOX": 2,
"REMOVE_POD_SANDBOX": 3,
"CREATE_CONTAINER": 4,
"POST_CREATE_CONTAINER": 5,
"START_CONTAINER": 6,
"POST_START_CONTAINER": 7,
"UPDATE_CONTAINER": 8,
"POST_UPDATE_CONTAINER": 9,
"STOP_CONTAINER": 10,
"REMOVE_CONTAINER": 11,
"LAST": 12,
}
)
func (x Event) Enum() *Event {
p := new(Event)
*p = x
return p
}
func (x Event) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (Event) Descriptor() protoreflect.EnumDescriptor {
return file_pkg_api_api_proto_enumTypes[0].Descriptor()
}
func (Event) Type() protoreflect.EnumType {
return &file_pkg_api_api_proto_enumTypes[0]
}
func (x Event) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use Event.Descriptor instead.
func (Event) EnumDescriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{0}
}
// Possible container states.
type ContainerState int32
const (
ContainerState_CONTAINER_UNKNOWN ContainerState = 0
ContainerState_CONTAINER_CREATED ContainerState = 1
ContainerState_CONTAINER_PAUSED ContainerState = 2 // is this useful/necessary ?
ContainerState_CONTAINER_RUNNING ContainerState = 3
ContainerState_CONTAINER_STOPPED ContainerState = 4
)
// Enum value maps for ContainerState.
var (
ContainerState_name = map[int32]string{
0: "CONTAINER_UNKNOWN",
1: "CONTAINER_CREATED",
2: "CONTAINER_PAUSED",
3: "CONTAINER_RUNNING",
4: "CONTAINER_STOPPED",
}
ContainerState_value = map[string]int32{
"CONTAINER_UNKNOWN": 0,
"CONTAINER_CREATED": 1,
"CONTAINER_PAUSED": 2,
"CONTAINER_RUNNING": 3,
"CONTAINER_STOPPED": 4,
}
)
func (x ContainerState) Enum() *ContainerState {
p := new(ContainerState)
*p = x
return p
}
func (x ContainerState) String() string {
return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
}
func (ContainerState) Descriptor() protoreflect.EnumDescriptor {
return file_pkg_api_api_proto_enumTypes[1].Descriptor()
}
func (ContainerState) Type() protoreflect.EnumType {
return &file_pkg_api_api_proto_enumTypes[1]
}
func (x ContainerState) Number() protoreflect.EnumNumber {
return protoreflect.EnumNumber(x)
}
// Deprecated: Use ContainerState.Descriptor instead.
func (ContainerState) EnumDescriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{1}
}
type RegisterPluginRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Name of the plugin to register.
PluginName string `protobuf:"bytes,1,opt,name=plugin_name,json=pluginName,proto3" json:"plugin_name,omitempty"`
// Plugin invocation index. Plugins are called in ascending index order.
PluginIdx string `protobuf:"bytes,2,opt,name=plugin_idx,json=pluginIdx,proto3" json:"plugin_idx,omitempty"`
}
func (x *RegisterPluginRequest) Reset() {
*x = RegisterPluginRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *RegisterPluginRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*RegisterPluginRequest) ProtoMessage() {}
func (x *RegisterPluginRequest) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 RegisterPluginRequest.ProtoReflect.Descriptor instead.
func (*RegisterPluginRequest) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{0}
}
func (x *RegisterPluginRequest) GetPluginName() string {
if x != nil {
return x.PluginName
}
return ""
}
func (x *RegisterPluginRequest) GetPluginIdx() string {
if x != nil {
return x.PluginIdx
}
return ""
}
type UpdateContainersRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// List of containers to update.
Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"`
// List of containers to evict.
Evict []*ContainerEviction `protobuf:"bytes,2,rep,name=evict,proto3" json:"evict,omitempty"`
}
func (x *UpdateContainersRequest) Reset() {
*x = UpdateContainersRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateContainersRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateContainersRequest) ProtoMessage() {}
func (x *UpdateContainersRequest) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 UpdateContainersRequest.ProtoReflect.Descriptor instead.
func (*UpdateContainersRequest) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{1}
}
func (x *UpdateContainersRequest) GetUpdate() []*ContainerUpdate {
if x != nil {
return x.Update
}
return nil
}
func (x *UpdateContainersRequest) GetEvict() []*ContainerEviction {
if x != nil {
return x.Evict
}
return nil
}
type UpdateContainersResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Containers that the runtime failed to udpate.
Failed []*ContainerUpdate `protobuf:"bytes,1,rep,name=failed,proto3" json:"failed,omitempty"`
}
func (x *UpdateContainersResponse) Reset() {
*x = UpdateContainersResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UpdateContainersResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UpdateContainersResponse) ProtoMessage() {}
func (x *UpdateContainersResponse) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 UpdateContainersResponse.ProtoReflect.Descriptor instead.
func (*UpdateContainersResponse) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{2}
}
func (x *UpdateContainersResponse) GetFailed() []*ContainerUpdate {
if x != nil {
return x.Failed
}
return nil
}
type ConfigureRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Any plugin-specific data, if present among the NRI configuration.
Config string `protobuf:"bytes,1,opt,name=config,proto3" json:"config,omitempty"`
// Name of the runtime NRI is running in.
RuntimeName string `protobuf:"bytes,2,opt,name=runtime_name,json=runtimeName,proto3" json:"runtime_name,omitempty"`
// Version of the runtime NRI is running in.
RuntimeVersion string `protobuf:"bytes,3,opt,name=runtime_version,json=runtimeVersion,proto3" json:"runtime_version,omitempty"`
}
func (x *ConfigureRequest) Reset() {
*x = ConfigureRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ConfigureRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ConfigureRequest) ProtoMessage() {}
func (x *ConfigureRequest) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 ConfigureRequest.ProtoReflect.Descriptor instead.
func (*ConfigureRequest) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{3}
}
func (x *ConfigureRequest) GetConfig() string {
if x != nil {
return x.Config
}
return ""
}
func (x *ConfigureRequest) GetRuntimeName() string {
if x != nil {
return x.RuntimeName
}
return ""
}
func (x *ConfigureRequest) GetRuntimeVersion() string {
if x != nil {
return x.RuntimeVersion
}
return ""
}
type ConfigureResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Events to subscribe the plugin for. Each bit set corresponds to an
// enumerated Event.
Events int32 `protobuf:"varint,2,opt,name=events,proto3" json:"events,omitempty"`
}
func (x *ConfigureResponse) Reset() {
*x = ConfigureResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ConfigureResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ConfigureResponse) ProtoMessage() {}
func (x *ConfigureResponse) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 ConfigureResponse.ProtoReflect.Descriptor instead.
func (*ConfigureResponse) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{4}
}
func (x *ConfigureResponse) GetEvents() int32 {
if x != nil {
return x.Events
}
return 0
}
type SynchronizeRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Pods known to the runtime.
Pods []*PodSandbox `protobuf:"bytes,1,rep,name=pods,proto3" json:"pods,omitempty"`
// Containers known to the runtime.
Containers []*Container `protobuf:"bytes,2,rep,name=containers,proto3" json:"containers,omitempty"`
}
func (x *SynchronizeRequest) Reset() {
*x = SynchronizeRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SynchronizeRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SynchronizeRequest) ProtoMessage() {}
func (x *SynchronizeRequest) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 SynchronizeRequest.ProtoReflect.Descriptor instead.
func (*SynchronizeRequest) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{5}
}
func (x *SynchronizeRequest) GetPods() []*PodSandbox {
if x != nil {
return x.Pods
}
return nil
}
func (x *SynchronizeRequest) GetContainers() []*Container {
if x != nil {
return x.Containers
}
return nil
}
type SynchronizeResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Updates to containers requested by the plugin.
Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"`
}
func (x *SynchronizeResponse) Reset() {
*x = SynchronizeResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *SynchronizeResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*SynchronizeResponse) ProtoMessage() {}
func (x *SynchronizeResponse) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 SynchronizeResponse.ProtoReflect.Descriptor instead.
func (*SynchronizeResponse) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{6}
}
func (x *SynchronizeResponse) GetUpdate() []*ContainerUpdate {
if x != nil {
return x.Update
}
return nil
}
type CreateContainerRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Pod of container being created.
Pod *PodSandbox `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"`
// Container being created.
Container *Container `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"`
}
func (x *CreateContainerRequest) Reset() {
*x = CreateContainerRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[7]
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_pkg_api_api_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 CreateContainerRequest.ProtoReflect.Descriptor instead.
func (*CreateContainerRequest) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{7}
}
func (x *CreateContainerRequest) GetPod() *PodSandbox {
if x != nil {
return x.Pod
}
return nil
}
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
// Requested adjustments to container being created.
Adjust *ContainerAdjustment `protobuf:"bytes,1,opt,name=adjust,proto3" json:"adjust,omitempty"`
// Requested updates to other existing containers.
Update []*ContainerUpdate `protobuf:"bytes,2,rep,name=update,proto3" json:"update,omitempty"`
// Requested eviction of existing containers.
Evict []*ContainerEviction `protobuf:"bytes,3,rep,name=evict,proto3" json:"evict,omitempty"`
}
func (x *CreateContainerResponse) Reset() {
*x = CreateContainerResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[8]
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_pkg_api_api_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 CreateContainerResponse.ProtoReflect.Descriptor instead.
func (*CreateContainerResponse) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{8}
}
func (x *CreateContainerResponse) GetAdjust() *ContainerAdjustment {
if x != nil {
return x.Adjust
}
return nil
}
func (x *CreateContainerResponse) GetUpdate() []*ContainerUpdate {
if x != nil {
return x.Update
}
return nil
}
func (x *CreateContainerResponse) GetEvict() []*ContainerEviction {
if x != nil {
return x.Evict
}
return nil
}
type UpdateContainerRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Pod of container being updated.
Pod *PodSandbox `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"`
// Container being updated.
Container *Container `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"`
// Resources to update.
LinuxResources *LinuxResources `protobuf:"bytes,3,opt,name=linux_resources,json=linuxResources,proto3" json:"linux_resources,omitempty"`
}
func (x *UpdateContainerRequest) Reset() {
*x = UpdateContainerRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[9]
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_pkg_api_api_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 UpdateContainerRequest.ProtoReflect.Descriptor instead.
func (*UpdateContainerRequest) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{9}
}
func (x *UpdateContainerRequest) GetPod() *PodSandbox {
if x != nil {
return x.Pod
}
return nil
}
func (x *UpdateContainerRequest) GetContainer() *Container {
if x != nil {
return x.Container
}
return nil
}
func (x *UpdateContainerRequest) GetLinuxResources() *LinuxResources {
if x != nil {
return x.LinuxResources
}
return nil
}
type UpdateContainerResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Requested updates to containers.
Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"`
// Requested eviction of containers.
Evict []*ContainerEviction `protobuf:"bytes,2,rep,name=evict,proto3" json:"evict,omitempty"`
}
func (x *UpdateContainerResponse) Reset() {
*x = UpdateContainerResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[10]
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_pkg_api_api_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 UpdateContainerResponse.ProtoReflect.Descriptor instead.
func (*UpdateContainerResponse) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{10}
}
func (x *UpdateContainerResponse) GetUpdate() []*ContainerUpdate {
if x != nil {
return x.Update
}
return nil
}
func (x *UpdateContainerResponse) GetEvict() []*ContainerEviction {
if x != nil {
return x.Evict
}
return nil
}
type StopContainerRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Pod of container being stopped.
Pod *PodSandbox `protobuf:"bytes,1,opt,name=pod,proto3" json:"pod,omitempty"`
// Container being stopped.
Container *Container `protobuf:"bytes,2,opt,name=container,proto3" json:"container,omitempty"`
}
func (x *StopContainerRequest) Reset() {
*x = StopContainerRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *StopContainerRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*StopContainerRequest) ProtoMessage() {}
func (x *StopContainerRequest) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 StopContainerRequest.ProtoReflect.Descriptor instead.
func (*StopContainerRequest) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{11}
}
func (x *StopContainerRequest) GetPod() *PodSandbox {
if x != nil {
return x.Pod
}
return nil
}
func (x *StopContainerRequest) GetContainer() *Container {
if x != nil {
return x.Container
}
return nil
}
type StopContainerResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Requested updates to containers.
Update []*ContainerUpdate `protobuf:"bytes,1,rep,name=update,proto3" json:"update,omitempty"`
}
func (x *StopContainerResponse) Reset() {
*x = StopContainerResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *StopContainerResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*StopContainerResponse) ProtoMessage() {}
func (x *StopContainerResponse) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 StopContainerResponse.ProtoReflect.Descriptor instead.
func (*StopContainerResponse) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{12}
}
func (x *StopContainerResponse) GetUpdate() []*ContainerUpdate {
if x != nil {
return x.Update
}
return nil
}
type StateChangeEvent struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Event type of notification.
Event Event `protobuf:"varint,1,opt,name=event,proto3,enum=nri.pkg.api.v1alpha1.Event" json:"event,omitempty"`
// Pod this notification is sent for. If this event is related to a container,
// pod is set to the pod of the container.
Pod *PodSandbox `protobuf:"bytes,2,opt,name=pod,proto3" json:"pod,omitempty"`
// Container this notification is sent for. If the event is related to a pod,
// container is nil.
Container *Container `protobuf:"bytes,3,opt,name=container,proto3" json:"container,omitempty"`
}
func (x *StateChangeEvent) Reset() {
*x = StateChangeEvent{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *StateChangeEvent) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*StateChangeEvent) ProtoMessage() {}
func (x *StateChangeEvent) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 StateChangeEvent.ProtoReflect.Descriptor instead.
func (*StateChangeEvent) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{13}
}
func (x *StateChangeEvent) GetEvent() Event {
if x != nil {
return x.Event
}
return Event_UNKNOWN
}
func (x *StateChangeEvent) GetPod() *PodSandbox {
if x != nil {
return x.Pod
}
return nil
}
func (x *StateChangeEvent) GetContainer() *Container {
if x != nil {
return x.Container
}
return nil
}
// Empty response for those *Requests that are semantically events.
type Empty struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
}
func (x *Empty) Reset() {
*x = Empty{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[14]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Empty) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Empty) ProtoMessage() {}
func (x *Empty) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 Empty.ProtoReflect.Descriptor instead.
func (*Empty) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{14}
}
// Pod metadata that is considered relevant for a plugin.
type PodSandbox struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Uid string `protobuf:"bytes,3,opt,name=uid,proto3" json:"uid,omitempty"`
Namespace string `protobuf:"bytes,4,opt,name=namespace,proto3" json:"namespace,omitempty"`
Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Annotations map[string]string `protobuf:"bytes,6,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
RuntimeHandler string `protobuf:"bytes,7,opt,name=runtime_handler,json=runtimeHandler,proto3" json:"runtime_handler,omitempty"`
Linux *LinuxPodSandbox `protobuf:"bytes,8,opt,name=linux,proto3" json:"linux,omitempty"`
Pid uint32 `protobuf:"varint,9,opt,name=pid,proto3" json:"pid,omitempty"` // for NRI v1 emulation
}
func (x *PodSandbox) Reset() {
*x = PodSandbox{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[15]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *PodSandbox) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*PodSandbox) ProtoMessage() {}
func (x *PodSandbox) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 PodSandbox.ProtoReflect.Descriptor instead.
func (*PodSandbox) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{15}
}
func (x *PodSandbox) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *PodSandbox) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *PodSandbox) GetUid() string {
if x != nil {
return x.Uid
}
return ""
}
func (x *PodSandbox) GetNamespace() string {
if x != nil {
return x.Namespace
}
return ""
}
func (x *PodSandbox) GetLabels() map[string]string {
if x != nil {
return x.Labels
}
return nil
}
func (x *PodSandbox) GetAnnotations() map[string]string {
if x != nil {
return x.Annotations
}
return nil
}
func (x *PodSandbox) GetRuntimeHandler() string {
if x != nil {
return x.RuntimeHandler
}
return ""
}
func (x *PodSandbox) GetLinux() *LinuxPodSandbox {
if x != nil {
return x.Linux
}
return nil
}
func (x *PodSandbox) GetPid() uint32 {
if x != nil {
return x.Pid
}
return 0
}
// PodSandbox linux-specific metadata
type LinuxPodSandbox struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
PodOverhead *LinuxResources `protobuf:"bytes,1,opt,name=pod_overhead,json=podOverhead,proto3" json:"pod_overhead,omitempty"`
PodResources *LinuxResources `protobuf:"bytes,2,opt,name=pod_resources,json=podResources,proto3" json:"pod_resources,omitempty"`
CgroupParent string `protobuf:"bytes,3,opt,name=cgroup_parent,json=cgroupParent,proto3" json:"cgroup_parent,omitempty"`
CgroupsPath string `protobuf:"bytes,4,opt,name=cgroups_path,json=cgroupsPath,proto3" json:"cgroups_path,omitempty"` // for NRI v1 emulation
Namespaces []*LinuxNamespace `protobuf:"bytes,5,rep,name=namespaces,proto3" json:"namespaces,omitempty"` // for NRI v1 emulation
Resources *LinuxResources `protobuf:"bytes,6,opt,name=resources,proto3" json:"resources,omitempty"` // for NRI v1 emulation
}
func (x *LinuxPodSandbox) Reset() {
*x = LinuxPodSandbox{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[16]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxPodSandbox) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxPodSandbox) ProtoMessage() {}
func (x *LinuxPodSandbox) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 LinuxPodSandbox.ProtoReflect.Descriptor instead.
func (*LinuxPodSandbox) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{16}
}
func (x *LinuxPodSandbox) GetPodOverhead() *LinuxResources {
if x != nil {
return x.PodOverhead
}
return nil
}
func (x *LinuxPodSandbox) GetPodResources() *LinuxResources {
if x != nil {
return x.PodResources
}
return nil
}
func (x *LinuxPodSandbox) GetCgroupParent() string {
if x != nil {
return x.CgroupParent
}
return ""
}
func (x *LinuxPodSandbox) GetCgroupsPath() string {
if x != nil {
return x.CgroupsPath
}
return ""
}
func (x *LinuxPodSandbox) GetNamespaces() []*LinuxNamespace {
if x != nil {
return x.Namespaces
}
return nil
}
func (x *LinuxPodSandbox) GetResources() *LinuxResources {
if x != nil {
return x.Resources
}
return nil
}
// Container metadata that is considered relevant for a plugin.
type Container struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
PodSandboxId string `protobuf:"bytes,2,opt,name=pod_sandbox_id,json=podSandboxId,proto3" json:"pod_sandbox_id,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
State ContainerState `protobuf:"varint,4,opt,name=state,proto3,enum=nri.pkg.api.v1alpha1.ContainerState" json:"state,omitempty"`
Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Annotations map[string]string `protobuf:"bytes,6,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Args []string `protobuf:"bytes,7,rep,name=args,proto3" json:"args,omitempty"`
Env []string `protobuf:"bytes,8,rep,name=env,proto3" json:"env,omitempty"`
Mounts []*Mount `protobuf:"bytes,9,rep,name=mounts,proto3" json:"mounts,omitempty"`
Hooks *Hooks `protobuf:"bytes,10,opt,name=hooks,proto3" json:"hooks,omitempty"`
Linux *LinuxContainer `protobuf:"bytes,11,opt,name=linux,proto3" json:"linux,omitempty"`
Pid uint32 `protobuf:"varint,12,opt,name=pid,proto3" json:"pid,omitempty"` // for NRI v1 emulation
Rlimits []*POSIXRlimit `protobuf:"bytes,13,rep,name=rlimits,proto3" json:"rlimits,omitempty"`
}
func (x *Container) Reset() {
*x = Container{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[17]
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_pkg_api_api_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 Container.ProtoReflect.Descriptor instead.
func (*Container) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{17}
}
func (x *Container) GetId() string {
if x != nil {
return x.Id
}
return ""
}
func (x *Container) GetPodSandboxId() string {
if x != nil {
return x.PodSandboxId
}
return ""
}
func (x *Container) GetName() string {
if x != nil {
return x.Name
}
return ""
}
func (x *Container) GetState() ContainerState {
if x != nil {
return x.State
}
return ContainerState_CONTAINER_UNKNOWN
}
func (x *Container) GetLabels() map[string]string {
if x != nil {
return x.Labels
}
return nil
}
func (x *Container) GetAnnotations() map[string]string {
if x != nil {
return x.Annotations
}
return nil
}
func (x *Container) GetArgs() []string {
if x != nil {
return x.Args
}
return nil
}
func (x *Container) GetEnv() []string {
if x != nil {
return x.Env
}
return nil
}
func (x *Container) GetMounts() []*Mount {
if x != nil {
return x.Mounts
}
return nil
}
func (x *Container) GetHooks() *Hooks {
if x != nil {
return x.Hooks
}
return nil
}
func (x *Container) GetLinux() *LinuxContainer {
if x != nil {
return x.Linux
}
return nil
}
func (x *Container) GetPid() uint32 {
if x != nil {
return x.Pid
}
return 0
}
func (x *Container) GetRlimits() []*POSIXRlimit {
if x != nil {
return x.Rlimits
}
return nil
}
// A container mount.
type Mount struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Destination string `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Source string `protobuf:"bytes,3,opt,name=source,proto3" json:"source,omitempty"`
Options []string `protobuf:"bytes,4,rep,name=options,proto3" json:"options,omitempty"`
}
func (x *Mount) Reset() {
*x = Mount{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[18]
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_pkg_api_api_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 Mount.ProtoReflect.Descriptor instead.
func (*Mount) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{18}
}
func (x *Mount) GetDestination() string {
if x != nil {
return x.Destination
}
return ""
}
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) GetOptions() []string {
if x != nil {
return x.Options
}
return nil
}
// Container OCI hooks.
type Hooks struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Prestart []*Hook `protobuf:"bytes,1,rep,name=prestart,proto3" json:"prestart,omitempty"`
CreateRuntime []*Hook `protobuf:"bytes,2,rep,name=create_runtime,json=createRuntime,proto3" json:"create_runtime,omitempty"`
CreateContainer []*Hook `protobuf:"bytes,3,rep,name=create_container,json=createContainer,proto3" json:"create_container,omitempty"`
StartContainer []*Hook `protobuf:"bytes,4,rep,name=start_container,json=startContainer,proto3" json:"start_container,omitempty"`
Poststart []*Hook `protobuf:"bytes,5,rep,name=poststart,proto3" json:"poststart,omitempty"`
Poststop []*Hook `protobuf:"bytes,6,rep,name=poststop,proto3" json:"poststop,omitempty"`
}
func (x *Hooks) Reset() {
*x = Hooks{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[19]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Hooks) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Hooks) ProtoMessage() {}
func (x *Hooks) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 Hooks.ProtoReflect.Descriptor instead.
func (*Hooks) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{19}
}
func (x *Hooks) GetPrestart() []*Hook {
if x != nil {
return x.Prestart
}
return nil
}
func (x *Hooks) GetCreateRuntime() []*Hook {
if x != nil {
return x.CreateRuntime
}
return nil
}
func (x *Hooks) GetCreateContainer() []*Hook {
if x != nil {
return x.CreateContainer
}
return nil
}
func (x *Hooks) GetStartContainer() []*Hook {
if x != nil {
return x.StartContainer
}
return nil
}
func (x *Hooks) GetPoststart() []*Hook {
if x != nil {
return x.Poststart
}
return nil
}
func (x *Hooks) GetPoststop() []*Hook {
if x != nil {
return x.Poststop
}
return nil
}
// One OCI hook.
type Hook struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
Args []string `protobuf:"bytes,2,rep,name=args,proto3" json:"args,omitempty"`
Env []string `protobuf:"bytes,3,rep,name=env,proto3" json:"env,omitempty"`
Timeout *OptionalInt `protobuf:"bytes,4,opt,name=timeout,proto3" json:"timeout,omitempty"`
}
func (x *Hook) Reset() {
*x = Hook{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[20]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Hook) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Hook) ProtoMessage() {}
func (x *Hook) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 Hook.ProtoReflect.Descriptor instead.
func (*Hook) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{20}
}
func (x *Hook) GetPath() string {
if x != nil {
return x.Path
}
return ""
}
func (x *Hook) GetArgs() []string {
if x != nil {
return x.Args
}
return nil
}
func (x *Hook) GetEnv() []string {
if x != nil {
return x.Env
}
return nil
}
func (x *Hook) GetTimeout() *OptionalInt {
if x != nil {
return x.Timeout
}
return nil
}
// Container (linux) metadata.
type LinuxContainer struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Namespaces []*LinuxNamespace `protobuf:"bytes,1,rep,name=namespaces,proto3" json:"namespaces,omitempty"`
Devices []*LinuxDevice `protobuf:"bytes,2,rep,name=devices,proto3" json:"devices,omitempty"`
Resources *LinuxResources `protobuf:"bytes,3,opt,name=resources,proto3" json:"resources,omitempty"`
OomScoreAdj *OptionalInt `protobuf:"bytes,4,opt,name=oom_score_adj,json=oomScoreAdj,proto3" json:"oom_score_adj,omitempty"`
CgroupsPath string `protobuf:"bytes,5,opt,name=cgroups_path,json=cgroupsPath,proto3" json:"cgroups_path,omitempty"`
}
func (x *LinuxContainer) Reset() {
*x = LinuxContainer{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[21]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxContainer) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxContainer) ProtoMessage() {}
func (x *LinuxContainer) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 LinuxContainer.ProtoReflect.Descriptor instead.
func (*LinuxContainer) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{21}
}
func (x *LinuxContainer) GetNamespaces() []*LinuxNamespace {
if x != nil {
return x.Namespaces
}
return nil
}
func (x *LinuxContainer) GetDevices() []*LinuxDevice {
if x != nil {
return x.Devices
}
return nil
}
func (x *LinuxContainer) GetResources() *LinuxResources {
if x != nil {
return x.Resources
}
return nil
}
func (x *LinuxContainer) GetOomScoreAdj() *OptionalInt {
if x != nil {
return x.OomScoreAdj
}
return nil
}
func (x *LinuxContainer) GetCgroupsPath() string {
if x != nil {
return x.CgroupsPath
}
return ""
}
// A linux namespace.
type LinuxNamespace struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"`
}
func (x *LinuxNamespace) Reset() {
*x = LinuxNamespace{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[22]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxNamespace) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxNamespace) ProtoMessage() {}
func (x *LinuxNamespace) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 LinuxNamespace.ProtoReflect.Descriptor instead.
func (*LinuxNamespace) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{22}
}
func (x *LinuxNamespace) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *LinuxNamespace) GetPath() string {
if x != nil {
return x.Path
}
return ""
}
// A container (linux) device.
type LinuxDevice struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Major int64 `protobuf:"varint,3,opt,name=major,proto3" json:"major,omitempty"`
Minor int64 `protobuf:"varint,4,opt,name=minor,proto3" json:"minor,omitempty"`
FileMode *OptionalFileMode `protobuf:"bytes,5,opt,name=file_mode,json=fileMode,proto3" json:"file_mode,omitempty"`
Uid *OptionalUInt32 `protobuf:"bytes,6,opt,name=uid,proto3" json:"uid,omitempty"`
Gid *OptionalUInt32 `protobuf:"bytes,7,opt,name=gid,proto3" json:"gid,omitempty"`
}
func (x *LinuxDevice) Reset() {
*x = LinuxDevice{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[23]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxDevice) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxDevice) ProtoMessage() {}
func (x *LinuxDevice) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 LinuxDevice.ProtoReflect.Descriptor instead.
func (*LinuxDevice) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{23}
}
func (x *LinuxDevice) GetPath() string {
if x != nil {
return x.Path
}
return ""
}
func (x *LinuxDevice) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *LinuxDevice) GetMajor() int64 {
if x != nil {
return x.Major
}
return 0
}
func (x *LinuxDevice) GetMinor() int64 {
if x != nil {
return x.Minor
}
return 0
}
func (x *LinuxDevice) GetFileMode() *OptionalFileMode {
if x != nil {
return x.FileMode
}
return nil
}
func (x *LinuxDevice) GetUid() *OptionalUInt32 {
if x != nil {
return x.Uid
}
return nil
}
func (x *LinuxDevice) GetGid() *OptionalUInt32 {
if x != nil {
return x.Gid
}
return nil
}
// A linux device cgroup controller rule.
type LinuxDeviceCgroup struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Allow bool `protobuf:"varint,1,opt,name=allow,proto3" json:"allow,omitempty"`
Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"`
Major *OptionalInt64 `protobuf:"bytes,3,opt,name=major,proto3" json:"major,omitempty"`
Minor *OptionalInt64 `protobuf:"bytes,4,opt,name=minor,proto3" json:"minor,omitempty"`
Access string `protobuf:"bytes,5,opt,name=access,proto3" json:"access,omitempty"`
}
func (x *LinuxDeviceCgroup) Reset() {
*x = LinuxDeviceCgroup{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[24]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxDeviceCgroup) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxDeviceCgroup) ProtoMessage() {}
func (x *LinuxDeviceCgroup) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 LinuxDeviceCgroup.ProtoReflect.Descriptor instead.
func (*LinuxDeviceCgroup) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{24}
}
func (x *LinuxDeviceCgroup) GetAllow() bool {
if x != nil {
return x.Allow
}
return false
}
func (x *LinuxDeviceCgroup) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *LinuxDeviceCgroup) GetMajor() *OptionalInt64 {
if x != nil {
return x.Major
}
return nil
}
func (x *LinuxDeviceCgroup) GetMinor() *OptionalInt64 {
if x != nil {
return x.Minor
}
return nil
}
func (x *LinuxDeviceCgroup) GetAccess() string {
if x != nil {
return x.Access
}
return ""
}
// Container (linux) resources.
type LinuxResources struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Memory *LinuxMemory `protobuf:"bytes,1,opt,name=memory,proto3" json:"memory,omitempty"`
Cpu *LinuxCPU `protobuf:"bytes,2,opt,name=cpu,proto3" json:"cpu,omitempty"`
HugepageLimits []*HugepageLimit `protobuf:"bytes,3,rep,name=hugepage_limits,json=hugepageLimits,proto3" json:"hugepage_limits,omitempty"`
BlockioClass *OptionalString `protobuf:"bytes,4,opt,name=blockio_class,json=blockioClass,proto3" json:"blockio_class,omitempty"`
RdtClass *OptionalString `protobuf:"bytes,5,opt,name=rdt_class,json=rdtClass,proto3" json:"rdt_class,omitempty"`
Unified map[string]string `protobuf:"bytes,6,rep,name=unified,proto3" json:"unified,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Devices []*LinuxDeviceCgroup `protobuf:"bytes,7,rep,name=devices,proto3" json:"devices,omitempty"` // for NRI v1 emulation
}
func (x *LinuxResources) Reset() {
*x = LinuxResources{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[25]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxResources) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxResources) ProtoMessage() {}
func (x *LinuxResources) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 LinuxResources.ProtoReflect.Descriptor instead.
func (*LinuxResources) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{25}
}
func (x *LinuxResources) GetMemory() *LinuxMemory {
if x != nil {
return x.Memory
}
return nil
}
func (x *LinuxResources) GetCpu() *LinuxCPU {
if x != nil {
return x.Cpu
}
return nil
}
func (x *LinuxResources) GetHugepageLimits() []*HugepageLimit {
if x != nil {
return x.HugepageLimits
}
return nil
}
func (x *LinuxResources) GetBlockioClass() *OptionalString {
if x != nil {
return x.BlockioClass
}
return nil
}
func (x *LinuxResources) GetRdtClass() *OptionalString {
if x != nil {
return x.RdtClass
}
return nil
}
func (x *LinuxResources) GetUnified() map[string]string {
if x != nil {
return x.Unified
}
return nil
}
func (x *LinuxResources) GetDevices() []*LinuxDeviceCgroup {
if x != nil {
return x.Devices
}
return nil
}
// Memory-related parts of (linux) resources.
type LinuxMemory struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Limit *OptionalInt64 `protobuf:"bytes,1,opt,name=limit,proto3" json:"limit,omitempty"`
Reservation *OptionalInt64 `protobuf:"bytes,2,opt,name=reservation,proto3" json:"reservation,omitempty"`
Swap *OptionalInt64 `protobuf:"bytes,3,opt,name=swap,proto3" json:"swap,omitempty"`
Kernel *OptionalInt64 `protobuf:"bytes,4,opt,name=kernel,proto3" json:"kernel,omitempty"`
KernelTcp *OptionalInt64 `protobuf:"bytes,5,opt,name=kernel_tcp,json=kernelTcp,proto3" json:"kernel_tcp,omitempty"`
Swappiness *OptionalUInt64 `protobuf:"bytes,6,opt,name=swappiness,proto3" json:"swappiness,omitempty"`
DisableOomKiller *OptionalBool `protobuf:"bytes,7,opt,name=disable_oom_killer,json=disableOomKiller,proto3" json:"disable_oom_killer,omitempty"`
UseHierarchy *OptionalBool `protobuf:"bytes,8,opt,name=use_hierarchy,json=useHierarchy,proto3" json:"use_hierarchy,omitempty"`
}
func (x *LinuxMemory) Reset() {
*x = LinuxMemory{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[26]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxMemory) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxMemory) ProtoMessage() {}
func (x *LinuxMemory) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_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 LinuxMemory.ProtoReflect.Descriptor instead.
func (*LinuxMemory) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{26}
}
func (x *LinuxMemory) GetLimit() *OptionalInt64 {
if x != nil {
return x.Limit
}
return nil
}
func (x *LinuxMemory) GetReservation() *OptionalInt64 {
if x != nil {
return x.Reservation
}
return nil
}
func (x *LinuxMemory) GetSwap() *OptionalInt64 {
if x != nil {
return x.Swap
}
return nil
}
func (x *LinuxMemory) GetKernel() *OptionalInt64 {
if x != nil {
return x.Kernel
}
return nil
}
func (x *LinuxMemory) GetKernelTcp() *OptionalInt64 {
if x != nil {
return x.KernelTcp
}
return nil
}
func (x *LinuxMemory) GetSwappiness() *OptionalUInt64 {
if x != nil {
return x.Swappiness
}
return nil
}
func (x *LinuxMemory) GetDisableOomKiller() *OptionalBool {
if x != nil {
return x.DisableOomKiller
}
return nil
}
func (x *LinuxMemory) GetUseHierarchy() *OptionalBool {
if x != nil {
return x.UseHierarchy
}
return nil
}
// CPU-related parts of (linux) resources.
type LinuxCPU struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Shares *OptionalUInt64 `protobuf:"bytes,1,opt,name=shares,proto3" json:"shares,omitempty"`
Quota *OptionalInt64 `protobuf:"bytes,2,opt,name=quota,proto3" json:"quota,omitempty"`
Period *OptionalUInt64 `protobuf:"bytes,3,opt,name=period,proto3" json:"period,omitempty"`
RealtimeRuntime *OptionalInt64 `protobuf:"bytes,4,opt,name=realtime_runtime,json=realtimeRuntime,proto3" json:"realtime_runtime,omitempty"`
RealtimePeriod *OptionalUInt64 `protobuf:"bytes,5,opt,name=realtime_period,json=realtimePeriod,proto3" json:"realtime_period,omitempty"`
Cpus string `protobuf:"bytes,6,opt,name=cpus,proto3" json:"cpus,omitempty"`
Mems string `protobuf:"bytes,7,opt,name=mems,proto3" json:"mems,omitempty"`
}
func (x *LinuxCPU) Reset() {
*x = LinuxCPU{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[27]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxCPU) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxCPU) ProtoMessage() {}
func (x *LinuxCPU) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[27]
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 LinuxCPU.ProtoReflect.Descriptor instead.
func (*LinuxCPU) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{27}
}
func (x *LinuxCPU) GetShares() *OptionalUInt64 {
if x != nil {
return x.Shares
}
return nil
}
func (x *LinuxCPU) GetQuota() *OptionalInt64 {
if x != nil {
return x.Quota
}
return nil
}
func (x *LinuxCPU) GetPeriod() *OptionalUInt64 {
if x != nil {
return x.Period
}
return nil
}
func (x *LinuxCPU) GetRealtimeRuntime() *OptionalInt64 {
if x != nil {
return x.RealtimeRuntime
}
return nil
}
func (x *LinuxCPU) GetRealtimePeriod() *OptionalUInt64 {
if x != nil {
return x.RealtimePeriod
}
return nil
}
func (x *LinuxCPU) GetCpus() string {
if x != nil {
return x.Cpus
}
return ""
}
func (x *LinuxCPU) GetMems() string {
if x != nil {
return x.Mems
}
return ""
}
// Container huge page limit.
type HugepageLimit struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
PageSize string `protobuf:"bytes,1,opt,name=page_size,json=pageSize,proto3" json:"page_size,omitempty"`
Limit uint64 `protobuf:"varint,2,opt,name=limit,proto3" json:"limit,omitempty"`
}
func (x *HugepageLimit) Reset() {
*x = HugepageLimit{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[28]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *HugepageLimit) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*HugepageLimit) ProtoMessage() {}
func (x *HugepageLimit) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[28]
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 HugepageLimit.ProtoReflect.Descriptor instead.
func (*HugepageLimit) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{28}
}
func (x *HugepageLimit) GetPageSize() string {
if x != nil {
return x.PageSize
}
return ""
}
func (x *HugepageLimit) GetLimit() uint64 {
if x != nil {
return x.Limit
}
return 0
}
// Container rlimits
type POSIXRlimit struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"`
Hard uint64 `protobuf:"varint,2,opt,name=hard,proto3" json:"hard,omitempty"`
Soft uint64 `protobuf:"varint,3,opt,name=soft,proto3" json:"soft,omitempty"`
}
func (x *POSIXRlimit) Reset() {
*x = POSIXRlimit{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[29]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *POSIXRlimit) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*POSIXRlimit) ProtoMessage() {}
func (x *POSIXRlimit) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[29]
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 POSIXRlimit.ProtoReflect.Descriptor instead.
func (*POSIXRlimit) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{29}
}
func (x *POSIXRlimit) GetType() string {
if x != nil {
return x.Type
}
return ""
}
func (x *POSIXRlimit) GetHard() uint64 {
if x != nil {
return x.Hard
}
return 0
}
func (x *POSIXRlimit) GetSoft() uint64 {
if x != nil {
return x.Soft
}
return 0
}
// Requested adjustments to a container being created.
type ContainerAdjustment struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Annotations map[string]string `protobuf:"bytes,2,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Mounts []*Mount `protobuf:"bytes,3,rep,name=mounts,proto3" json:"mounts,omitempty"`
Env []*KeyValue `protobuf:"bytes,4,rep,name=env,proto3" json:"env,omitempty"`
Hooks *Hooks `protobuf:"bytes,5,opt,name=hooks,proto3" json:"hooks,omitempty"`
Linux *LinuxContainerAdjustment `protobuf:"bytes,6,opt,name=linux,proto3" json:"linux,omitempty"`
Rlimits []*POSIXRlimit `protobuf:"bytes,7,rep,name=rlimits,proto3" json:"rlimits,omitempty"`
}
func (x *ContainerAdjustment) Reset() {
*x = ContainerAdjustment{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[30]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ContainerAdjustment) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ContainerAdjustment) ProtoMessage() {}
func (x *ContainerAdjustment) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[30]
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 ContainerAdjustment.ProtoReflect.Descriptor instead.
func (*ContainerAdjustment) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{30}
}
func (x *ContainerAdjustment) GetAnnotations() map[string]string {
if x != nil {
return x.Annotations
}
return nil
}
func (x *ContainerAdjustment) GetMounts() []*Mount {
if x != nil {
return x.Mounts
}
return nil
}
func (x *ContainerAdjustment) GetEnv() []*KeyValue {
if x != nil {
return x.Env
}
return nil
}
func (x *ContainerAdjustment) GetHooks() *Hooks {
if x != nil {
return x.Hooks
}
return nil
}
func (x *ContainerAdjustment) GetLinux() *LinuxContainerAdjustment {
if x != nil {
return x.Linux
}
return nil
}
func (x *ContainerAdjustment) GetRlimits() []*POSIXRlimit {
if x != nil {
return x.Rlimits
}
return nil
}
// Adjustments to (linux) resources.
type LinuxContainerAdjustment struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Devices []*LinuxDevice `protobuf:"bytes,1,rep,name=devices,proto3" json:"devices,omitempty"`
Resources *LinuxResources `protobuf:"bytes,2,opt,name=resources,proto3" json:"resources,omitempty"`
CgroupsPath string `protobuf:"bytes,3,opt,name=cgroups_path,json=cgroupsPath,proto3" json:"cgroups_path,omitempty"`
}
func (x *LinuxContainerAdjustment) Reset() {
*x = LinuxContainerAdjustment{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[31]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxContainerAdjustment) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxContainerAdjustment) ProtoMessage() {}
func (x *LinuxContainerAdjustment) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[31]
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 LinuxContainerAdjustment.ProtoReflect.Descriptor instead.
func (*LinuxContainerAdjustment) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{31}
}
func (x *LinuxContainerAdjustment) GetDevices() []*LinuxDevice {
if x != nil {
return x.Devices
}
return nil
}
func (x *LinuxContainerAdjustment) GetResources() *LinuxResources {
if x != nil {
return x.Resources
}
return nil
}
func (x *LinuxContainerAdjustment) GetCgroupsPath() string {
if x != nil {
return x.CgroupsPath
}
return ""
}
// Requested update to an already created container.
type ContainerUpdate 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"`
Linux *LinuxContainerUpdate `protobuf:"bytes,2,opt,name=linux,proto3" json:"linux,omitempty"`
IgnoreFailure bool `protobuf:"varint,3,opt,name=ignore_failure,json=ignoreFailure,proto3" json:"ignore_failure,omitempty"`
}
func (x *ContainerUpdate) Reset() {
*x = ContainerUpdate{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[32]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ContainerUpdate) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ContainerUpdate) ProtoMessage() {}
func (x *ContainerUpdate) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[32]
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 ContainerUpdate.ProtoReflect.Descriptor instead.
func (*ContainerUpdate) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{32}
}
func (x *ContainerUpdate) GetContainerId() string {
if x != nil {
return x.ContainerId
}
return ""
}
func (x *ContainerUpdate) GetLinux() *LinuxContainerUpdate {
if x != nil {
return x.Linux
}
return nil
}
func (x *ContainerUpdate) GetIgnoreFailure() bool {
if x != nil {
return x.IgnoreFailure
}
return false
}
// Updates to (linux) resources.
type LinuxContainerUpdate struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Resources *LinuxResources `protobuf:"bytes,1,opt,name=resources,proto3" json:"resources,omitempty"`
}
func (x *LinuxContainerUpdate) Reset() {
*x = LinuxContainerUpdate{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[33]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LinuxContainerUpdate) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LinuxContainerUpdate) ProtoMessage() {}
func (x *LinuxContainerUpdate) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[33]
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 LinuxContainerUpdate.ProtoReflect.Descriptor instead.
func (*LinuxContainerUpdate) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{33}
}
func (x *LinuxContainerUpdate) GetResources() *LinuxResources {
if x != nil {
return x.Resources
}
return nil
}
// Request to evict (IOW unsolicitedly stop) a container.
type ContainerEviction struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// Container to evict.
ContainerId string `protobuf:"bytes,1,opt,name=container_id,json=containerId,proto3" json:"container_id,omitempty"`
// Human-readable reason for eviction.
Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"`
}
func (x *ContainerEviction) Reset() {
*x = ContainerEviction{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[34]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ContainerEviction) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ContainerEviction) ProtoMessage() {}
func (x *ContainerEviction) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[34]
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 ContainerEviction.ProtoReflect.Descriptor instead.
func (*ContainerEviction) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{34}
}
func (x *ContainerEviction) GetContainerId() string {
if x != nil {
return x.ContainerId
}
return ""
}
func (x *ContainerEviction) GetReason() string {
if x != nil {
return x.Reason
}
return ""
}
// KeyValue represents an environment variable.
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_pkg_api_api_proto_msgTypes[35]
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_pkg_api_api_proto_msgTypes[35]
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_pkg_api_api_proto_rawDescGZIP(), []int{35}
}
func (x *KeyValue) GetKey() string {
if x != nil {
return x.Key
}
return ""
}
func (x *KeyValue) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
// An optional string value.
type OptionalString struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalString) Reset() {
*x = OptionalString{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[36]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalString) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalString) ProtoMessage() {}
func (x *OptionalString) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[36]
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 OptionalString.ProtoReflect.Descriptor instead.
func (*OptionalString) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{36}
}
func (x *OptionalString) GetValue() string {
if x != nil {
return x.Value
}
return ""
}
// An optional signed integer value.
type OptionalInt struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalInt) Reset() {
*x = OptionalInt{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[37]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalInt) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalInt) ProtoMessage() {}
func (x *OptionalInt) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[37]
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 OptionalInt.ProtoReflect.Descriptor instead.
func (*OptionalInt) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{37}
}
func (x *OptionalInt) GetValue() int64 {
if x != nil {
return x.Value
}
return 0
}
// An optional 32-bit signed integer value.
type OptionalInt32 struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalInt32) Reset() {
*x = OptionalInt32{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[38]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalInt32) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalInt32) ProtoMessage() {}
func (x *OptionalInt32) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[38]
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 OptionalInt32.ProtoReflect.Descriptor instead.
func (*OptionalInt32) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{38}
}
func (x *OptionalInt32) GetValue() int32 {
if x != nil {
return x.Value
}
return 0
}
// An optional 32-bit unsigned integer value.
type OptionalUInt32 struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalUInt32) Reset() {
*x = OptionalUInt32{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[39]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalUInt32) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalUInt32) ProtoMessage() {}
func (x *OptionalUInt32) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[39]
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 OptionalUInt32.ProtoReflect.Descriptor instead.
func (*OptionalUInt32) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{39}
}
func (x *OptionalUInt32) GetValue() uint32 {
if x != nil {
return x.Value
}
return 0
}
// An optional 64-bit signed integer value.
type OptionalInt64 struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalInt64) Reset() {
*x = OptionalInt64{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[40]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalInt64) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalInt64) ProtoMessage() {}
func (x *OptionalInt64) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[40]
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 OptionalInt64.ProtoReflect.Descriptor instead.
func (*OptionalInt64) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{40}
}
func (x *OptionalInt64) GetValue() int64 {
if x != nil {
return x.Value
}
return 0
}
// An optional 64-bit unsigned integer value.
type OptionalUInt64 struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalUInt64) Reset() {
*x = OptionalUInt64{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[41]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalUInt64) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalUInt64) ProtoMessage() {}
func (x *OptionalUInt64) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[41]
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 OptionalUInt64.ProtoReflect.Descriptor instead.
func (*OptionalUInt64) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{41}
}
func (x *OptionalUInt64) GetValue() uint64 {
if x != nil {
return x.Value
}
return 0
}
// An optional boolean value.
type OptionalBool struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalBool) Reset() {
*x = OptionalBool{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[42]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalBool) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalBool) ProtoMessage() {}
func (x *OptionalBool) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[42]
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 OptionalBool.ProtoReflect.Descriptor instead.
func (*OptionalBool) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{42}
}
func (x *OptionalBool) GetValue() bool {
if x != nil {
return x.Value
}
return false
}
// An optional value of file permissions.
type OptionalFileMode struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
}
func (x *OptionalFileMode) Reset() {
*x = OptionalFileMode{}
if protoimpl.UnsafeEnabled {
mi := &file_pkg_api_api_proto_msgTypes[43]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *OptionalFileMode) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*OptionalFileMode) ProtoMessage() {}
func (x *OptionalFileMode) ProtoReflect() protoreflect.Message {
mi := &file_pkg_api_api_proto_msgTypes[43]
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 OptionalFileMode.ProtoReflect.Descriptor instead.
func (*OptionalFileMode) Descriptor() ([]byte, []int) {
return file_pkg_api_api_proto_rawDescGZIP(), []int{43}
}
func (x *OptionalFileMode) GetValue() uint32 {
if x != nil {
return x.Value
}
return 0
}
var File_pkg_api_api_proto protoreflect.FileDescriptor
var file_pkg_api_api_proto_rawDesc = []byte{
0x0a, 0x11, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x12, 0x14, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x22, 0x57, 0x0a, 0x15, 0x52, 0x65, 0x67,
0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x4e,
0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x5f, 0x69, 0x64,
0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x49,
0x64, 0x78, 0x22, 0x97, 0x01, 0x0a, 0x17, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3d,
0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25,
0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55,
0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a,
0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e,
0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x69,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x22, 0x59, 0x0a, 0x18,
0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c,
0x65, 0x64, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70,
0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52,
0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x22, 0x76, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x6e,
0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x75, 0x6e, 0x74, 0x69,
0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d,
0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
0x0e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22,
0x2b, 0x0a, 0x11, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x02,
0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x8b, 0x01, 0x0a,
0x12, 0x53, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x04, 0x70, 0x6f, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64,
0x62, 0x6f, 0x78, 0x52, 0x04, 0x70, 0x6f, 0x64, 0x73, 0x12, 0x3f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x0a,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x54, 0x0a, 0x13, 0x53, 0x79,
0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x12, 0x3d, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65,
0x22, 0x8b, 0x01, 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, 0x32, 0x0a, 0x03, 0x70,
0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70,
0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12,
0x3d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0xda,
0x01, 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, 0x41, 0x0a, 0x06, 0x61, 0x64,
0x6a, 0x75, 0x73, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6e, 0x72, 0x69,
0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73,
0x74, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x12, 0x3d, 0x0a,
0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70,
0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x05,
0x65, 0x76, 0x69, 0x63, 0x74, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x69, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x22, 0xda, 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, 0x32, 0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x01, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61,
0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x63, 0x6f,
0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09,
0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x4d, 0x0a, 0x0f, 0x6c, 0x69, 0x6e,
0x75, 0x78, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x0e, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x97, 0x01, 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, 0x3d, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x18, 0x01,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06, 0x75, 0x70, 0x64,
0x61, 0x74, 0x65, 0x12, 0x3d, 0x0a, 0x05, 0x65, 0x76, 0x69, 0x63, 0x74, 0x18, 0x02, 0x20, 0x03,
0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x45, 0x76, 0x69, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x65, 0x76, 0x69,
0x63, 0x74, 0x22, 0x89, 0x01, 0x0a, 0x14, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x32, 0x0a, 0x03, 0x70,
0x6f, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70,
0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70, 0x6f, 0x64, 0x12,
0x3d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x56,
0x0a, 0x15, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3d, 0x0a, 0x06, 0x75, 0x70, 0x64, 0x61, 0x74,
0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b,
0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x06,
0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x22, 0xb8, 0x01, 0x0a, 0x10, 0x53, 0x74, 0x61, 0x74, 0x65,
0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x31, 0x0a, 0x05, 0x65,
0x76, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x6e, 0x72, 0x69,
0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x32,
0x0a, 0x03, 0x70, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x03, 0x70,
0x6f, 0x64, 0x12, 0x3d, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x22, 0x07, 0x0a, 0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xee, 0x03, 0x0a, 0x0a, 0x50,
0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a,
0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12,
0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01,
0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x44, 0x0a,
0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x6f, 0x64, 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, 0x53, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70,
0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 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, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x75, 0x6e, 0x74,
0x69, 0x6d, 0x65, 0x5f, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65,
0x72, 0x12, 0x3b, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x25, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x50, 0x6f, 0x64,
0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x10,
0x0a, 0x03, 0x70, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64,
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, 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, 0xf7, 0x02, 0x0a, 0x0f,
0x4c, 0x69, 0x6e, 0x75, 0x78, 0x50, 0x6f, 0x64, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x12,
0x47, 0x0a, 0x0c, 0x70, 0x6f, 0x64, 0x5f, 0x6f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e,
0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x0b, 0x70, 0x6f, 0x64,
0x4f, 0x76, 0x65, 0x72, 0x68, 0x65, 0x61, 0x64, 0x12, 0x49, 0x0a, 0x0d, 0x70, 0x6f, 0x64, 0x5f,
0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x0c, 0x70, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x5f, 0x70, 0x61,
0x72, 0x65, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x67, 0x72, 0x6f,
0x75, 0x70, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x67, 0x72, 0x6f,
0x75, 0x70, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b,
0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x44, 0x0a, 0x0a, 0x6e,
0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4e, 0x61, 0x6d, 0x65,
0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x73, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x06,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75,
0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f,
0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0xbe, 0x05, 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, 0x24, 0x0a, 0x0e, 0x70, 0x6f, 0x64, 0x5f, 0x73, 0x61, 0x6e, 0x64, 0x62,
0x6f, 0x78, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x6f, 0x64,
0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x3a, 0x0a,
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x24, 0x2e, 0x6e,
0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61,
0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x06, 0x6c, 0x61, 0x62,
0x65, 0x6c, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x6e, 0x72, 0x69, 0x2e,
0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 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, 0x52,
0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 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, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x09,
0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18, 0x08, 0x20,
0x03, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x33, 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e,
0x74, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70,
0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x31, 0x0a,
0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e,
0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73,
0x12, 0x3a, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74,
0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x10, 0x0a, 0x03,
0x70, 0x69, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x70, 0x69, 0x64, 0x12, 0x3b,
0x0a, 0x07, 0x72, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32,
0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x4f, 0x53, 0x49, 0x58, 0x52, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x52, 0x07, 0x72, 0x6c, 0x69, 0x6d, 0x69, 0x74, 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, 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, 0x6f, 0x0a, 0x05, 0x4d, 0x6f, 0x75, 0x6e, 0x74, 0x12,
0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18,
0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 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, 0x22, 0x80, 0x03, 0x0a, 0x05, 0x48, 0x6f, 0x6f, 0x6b,
0x73, 0x12, 0x36, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52,
0x08, 0x70, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x41, 0x0a, 0x0e, 0x63, 0x72, 0x65,
0x61, 0x74, 0x65, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28,
0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x0d, 0x63,
0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x45, 0x0a, 0x10,
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f,
0x6f, 0x6b, 0x52, 0x0f, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x63, 0x6f, 0x6e,
0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e,
0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x43,
0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x38, 0x0a, 0x09, 0x70, 0x6f, 0x73, 0x74,
0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x52, 0x09, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x74, 0x61,
0x72, 0x74, 0x12, 0x36, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x74, 0x6f, 0x70, 0x18, 0x06,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x6f, 0x6f, 0x6b,
0x52, 0x08, 0x70, 0x6f, 0x73, 0x74, 0x73, 0x74, 0x6f, 0x70, 0x22, 0x7d, 0x0a, 0x04, 0x48, 0x6f,
0x6f, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02,
0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x65, 0x6e,
0x76, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x3b, 0x0a, 0x07,
0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74,
0x52, 0x07, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x22, 0xc1, 0x02, 0x0a, 0x0e, 0x4c, 0x69,
0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x44, 0x0a, 0x0a,
0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4e, 0x61, 0x6d,
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x52, 0x0a, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63,
0x65, 0x73, 0x12, 0x3b, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78,
0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12,
0x42, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52,
0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x12, 0x45, 0x0a, 0x0d, 0x6f, 0x6f, 0x6d, 0x5f, 0x73, 0x63, 0x6f, 0x72, 0x65,
0x5f, 0x61, 0x64, 0x6a, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69,
0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x52, 0x0b, 0x6f,
0x6f, 0x6d, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x41, 0x64, 0x6a, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x67,
0x72, 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74, 0x68, 0x22, 0x38, 0x0a,
0x0e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12,
0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74,
0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0x96, 0x02, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x75,
0x78, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74,
0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
0x14, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05,
0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04,
0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x43, 0x0a, 0x09, 0x66,
0x69, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26,
0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x46, 0x69,
0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x65,
0x12, 0x36, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e,
0x74, 0x33, 0x32, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x36, 0x0a, 0x03, 0x67, 0x69, 0x64, 0x18,
0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x52, 0x03, 0x67, 0x69, 0x64,
0x22, 0xcb, 0x01, 0x0a, 0x11, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65,
0x43, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x18,
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x12, 0x12, 0x0a, 0x04,
0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65,
0x12, 0x39, 0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32,
0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49,
0x6e, 0x74, 0x36, 0x34, 0x52, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x05, 0x6d,
0x69, 0x6e, 0x6f, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69,
0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52,
0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73,
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x22, 0xa5,
0x04, 0x0a, 0x0e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x73, 0x12, 0x39, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x4d, 0x65,
0x6d, 0x6f, 0x72, 0x79, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x30, 0x0a, 0x03,
0x63, 0x70, 0x75, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6e, 0x72, 0x69, 0x2e,
0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x50, 0x55, 0x52, 0x03, 0x63, 0x70, 0x75, 0x12, 0x4c,
0x0a, 0x0f, 0x68, 0x75, 0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74,
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b,
0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48,
0x75, 0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x0e, 0x68, 0x75,
0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x12, 0x49, 0x0a, 0x0d,
0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x6f, 0x5f, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x18, 0x04, 0x20,
0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f,
0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b,
0x69, 0x6f, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x41, 0x0a, 0x09, 0x72, 0x64, 0x74, 0x5f, 0x63,
0x6c, 0x61, 0x73, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69,
0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,
0x52, 0x08, 0x72, 0x64, 0x74, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x12, 0x4b, 0x0a, 0x07, 0x75, 0x6e,
0x69, 0x66, 0x69, 0x65, 0x64, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x73, 0x2e, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07,
0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x12, 0x41, 0x0a, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63,
0x65, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70,
0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e,
0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x43, 0x67, 0x72, 0x6f, 0x75,
0x70, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x1a, 0x3a, 0x0a, 0x0c, 0x55, 0x6e,
0x69, 0x66, 0x69, 0x65, 0x64, 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, 0xaa, 0x04, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, 0x75, 0x78,
0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x05, 0x6c, 0x69, 0x6d, 0x69,
0x74, 0x12, 0x45, 0x0a, 0x0b, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x0b, 0x72, 0x65, 0x73,
0x65, 0x72, 0x76, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x37, 0x0a, 0x04, 0x73, 0x77, 0x61, 0x70,
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x04, 0x73, 0x77, 0x61,
0x70, 0x12, 0x3b, 0x0a, 0x06, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61,
0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x06, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x12, 0x42,
0x0a, 0x0a, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x5f, 0x74, 0x63, 0x70, 0x18, 0x05, 0x20, 0x01,
0x28, 0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69,
0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x09, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x54,
0x63, 0x70, 0x12, 0x44, 0x0a, 0x0a, 0x73, 0x77, 0x61, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x73, 0x73,
0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67,
0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70,
0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x0a, 0x73, 0x77,
0x61, 0x70, 0x70, 0x69, 0x6e, 0x65, 0x73, 0x73, 0x12, 0x50, 0x0a, 0x12, 0x64, 0x69, 0x73, 0x61,
0x62, 0x6c, 0x65, 0x5f, 0x6f, 0x6f, 0x6d, 0x5f, 0x6b, 0x69, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x07,
0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x10, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c,
0x65, 0x4f, 0x6f, 0x6d, 0x4b, 0x69, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x47, 0x0a, 0x0d, 0x75, 0x73,
0x65, 0x5f, 0x68, 0x69, 0x65, 0x72, 0x61, 0x72, 0x63, 0x68, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x22, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61,
0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x52, 0x0c, 0x75, 0x73, 0x65, 0x48, 0x69, 0x65, 0x72, 0x61, 0x72,
0x63, 0x68, 0x79, 0x22, 0x88, 0x03, 0x0a, 0x08, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x50, 0x55,
0x12, 0x3c, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x73, 0x12, 0x39,
0x0a, 0x05, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74,
0x36, 0x34, 0x52, 0x05, 0x71, 0x75, 0x6f, 0x74, 0x61, 0x12, 0x3c, 0x0a, 0x06, 0x70, 0x65, 0x72,
0x69, 0x6f, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e,
0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52,
0x06, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x4e, 0x0a, 0x10, 0x72, 0x65, 0x61, 0x6c, 0x74,
0x69, 0x6d, 0x65, 0x5f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x23, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61,
0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x0f, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65,
0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x4d, 0x0a, 0x0f, 0x72, 0x65, 0x61, 0x6c, 0x74,
0x69, 0x6d, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x24, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76,
0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x52, 0x0e, 0x72, 0x65, 0x61, 0x6c, 0x74, 0x69, 0x6d, 0x65,
0x50, 0x65, 0x72, 0x69, 0x6f, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x70, 0x75, 0x73, 0x18, 0x06,
0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x70, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65,
0x6d, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x73, 0x22, 0x42,
0x0a, 0x0d, 0x48, 0x75, 0x67, 0x65, 0x70, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12,
0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x14, 0x0a, 0x05,
0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6c, 0x69, 0x6d,
0x69, 0x74, 0x22, 0x49, 0x0a, 0x0b, 0x50, 0x4f, 0x53, 0x49, 0x58, 0x52, 0x6c, 0x69, 0x6d, 0x69,
0x74, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x72, 0x64, 0x18, 0x02, 0x20,
0x01, 0x28, 0x04, 0x52, 0x04, 0x68, 0x61, 0x72, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6f, 0x66,
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x04, 0x73, 0x6f, 0x66, 0x74, 0x22, 0xd0, 0x03,
0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73,
0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x5c, 0x0a, 0x0b, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x6e, 0x72, 0x69,
0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73,
0x74, 0x6d, 0x65, 0x6e, 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, 0x12, 0x33, 0x0a, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20,
0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x75, 0x6e, 0x74,
0x52, 0x06, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x73, 0x12, 0x30, 0x0a, 0x03, 0x65, 0x6e, 0x76, 0x18,
0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e,
0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4b, 0x65, 0x79,
0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x03, 0x65, 0x6e, 0x76, 0x12, 0x31, 0x0a, 0x05, 0x68, 0x6f,
0x6f, 0x6b, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e,
0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
0x2e, 0x48, 0x6f, 0x6f, 0x6b, 0x73, 0x52, 0x05, 0x68, 0x6f, 0x6f, 0x6b, 0x73, 0x12, 0x44, 0x0a,
0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x6e,
0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x05, 0x6c, 0x69,
0x6e, 0x75, 0x78, 0x12, 0x3b, 0x0a, 0x07, 0x72, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x73, 0x18, 0x07,
0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x50, 0x4f, 0x53, 0x49,
0x58, 0x52, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x52, 0x07, 0x72, 0x6c, 0x69, 0x6d, 0x69, 0x74, 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, 0xbe, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x41, 0x64, 0x6a, 0x75, 0x73, 0x74, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x3b, 0x0a,
0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21,
0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x44, 0x65, 0x76, 0x69, 0x63,
0x65, 0x52, 0x07, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72,
0x63, 0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x21,
0x0a, 0x0c, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x03,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x50, 0x61, 0x74,
0x68, 0x22, 0x9d, 0x01, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55,
0x70, 0x64, 0x61, 0x74, 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, 0x40, 0x0a, 0x05, 0x6c, 0x69, 0x6e, 0x75,
0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b,
0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x4c,
0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x55, 0x70, 0x64,
0x61, 0x74, 0x65, 0x52, 0x05, 0x6c, 0x69, 0x6e, 0x75, 0x78, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x67,
0x6e, 0x6f, 0x72, 0x65, 0x5f, 0x66, 0x61, 0x69, 0x6c, 0x75, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01,
0x28, 0x08, 0x52, 0x0d, 0x69, 0x67, 0x6e, 0x6f, 0x72, 0x65, 0x46, 0x61, 0x69, 0x6c, 0x75, 0x72,
0x65, 0x22, 0x5a, 0x0a, 0x14, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x42, 0x0a, 0x09, 0x72, 0x65, 0x73,
0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6e,
0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x4c, 0x69, 0x6e, 0x75, 0x78, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x73, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x22, 0x4e, 0x0a,
0x11, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x45, 0x76, 0x69, 0x63, 0x74, 0x69,
0x6f, 0x6e, 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, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 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, 0x22, 0x26, 0x0a, 0x0e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x53, 0x74, 0x72,
0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x23, 0x0a, 0x0b, 0x4f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x25,
0x0a, 0x0d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12,
0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x26, 0x0a, 0x0e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61,
0x6c, 0x55, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x25, 0x0a,
0x0d, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x14,
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76,
0x61, 0x6c, 0x75, 0x65, 0x22, 0x26, 0x0a, 0x0e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c,
0x55, 0x49, 0x6e, 0x74, 0x36, 0x34, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x24, 0x0a, 0x0c,
0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x42, 0x6f, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05,
0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x76, 0x61, 0x6c,
0x75, 0x65, 0x22, 0x28, 0x0a, 0x10, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x46, 0x69,
0x6c, 0x65, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x9c, 0x02, 0x0a,
0x05, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
0x4e, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x52, 0x55, 0x4e, 0x5f, 0x50, 0x4f, 0x44, 0x5f, 0x53,
0x41, 0x4e, 0x44, 0x42, 0x4f, 0x58, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x54, 0x4f, 0x50,
0x5f, 0x50, 0x4f, 0x44, 0x5f, 0x53, 0x41, 0x4e, 0x44, 0x42, 0x4f, 0x58, 0x10, 0x02, 0x12, 0x16,
0x0a, 0x12, 0x52, 0x45, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x50, 0x4f, 0x44, 0x5f, 0x53, 0x41, 0x4e,
0x44, 0x42, 0x4f, 0x58, 0x10, 0x03, 0x12, 0x14, 0x0a, 0x10, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45,
0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x04, 0x12, 0x19, 0x0a, 0x15,
0x50, 0x4f, 0x53, 0x54, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54,
0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x54, 0x41, 0x52, 0x54,
0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x06, 0x12, 0x18, 0x0a, 0x14,
0x50, 0x4f, 0x53, 0x54, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41,
0x49, 0x4e, 0x45, 0x52, 0x10, 0x07, 0x12, 0x14, 0x0a, 0x10, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45,
0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x08, 0x12, 0x19, 0x0a, 0x15,
0x50, 0x4f, 0x53, 0x54, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54,
0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x09, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x54, 0x4f, 0x50, 0x5f,
0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10, 0x0a, 0x12, 0x14, 0x0a, 0x10, 0x52,
0x45, 0x4d, 0x4f, 0x56, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x10,
0x0b, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x41, 0x53, 0x54, 0x10, 0x0c, 0x2a, 0x82, 0x01, 0x0a, 0x0e,
0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x15,
0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x55, 0x4e, 0x4b, 0x4e,
0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e,
0x45, 0x52, 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x14, 0x0a, 0x10,
0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x50, 0x41, 0x55, 0x53, 0x45, 0x44,
0x10, 0x02, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e, 0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f,
0x52, 0x55, 0x4e, 0x4e, 0x49, 0x4e, 0x47, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x11, 0x43, 0x4f, 0x4e,
0x54, 0x41, 0x49, 0x4e, 0x45, 0x52, 0x5f, 0x53, 0x54, 0x4f, 0x50, 0x50, 0x45, 0x44, 0x10, 0x04,
0x32, 0xd8, 0x01, 0x0a, 0x07, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x5a, 0x0a, 0x0e,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x2b,
0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61,
0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x50, 0x6c,
0x75, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x71, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61,
0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x2d, 0x2e, 0x6e,
0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
0x68, 0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69,
0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xae, 0x05, 0x0a, 0x06,
0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x12, 0x5c, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x75, 0x72, 0x65, 0x12, 0x26, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0b, 0x53, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e,
0x69, 0x7a, 0x65, 0x12, 0x28, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70,
0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x68,
0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e,
0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c,
0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x68, 0x72, 0x6f, 0x6e, 0x69, 0x7a, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x44, 0x0a, 0x08, 0x53, 0x68, 0x75, 0x74,
0x64, 0x6f, 0x77, 0x6e, 0x12, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74,
0x79, 0x1a, 0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x6e,
0x0a, 0x0f, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x12, 0x2c, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 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,
0x2d, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 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, 0x6e,
0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65,
0x72, 0x12, 0x2c, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e,
0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 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,
0x2d, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 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, 0x68,
0x0a, 0x0d, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12,
0x2a, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6e, 0x72,
0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
0x61, 0x31, 0x2e, 0x53, 0x74, 0x6f, 0x70, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0b, 0x53, 0x74, 0x61, 0x74,
0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x26, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b,
0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x53,
0x74, 0x61, 0x74, 0x65, 0x43, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x1a,
0x1b, 0x2e, 0x6e, 0x72, 0x69, 0x2e, 0x70, 0x6b, 0x67, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x76, 0x31,
0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x27, 0x5a, 0x25,
0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x6e, 0x74, 0x61,
0x69, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x6e, 0x72, 0x69, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70,
0x69, 0x3b, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_pkg_api_api_proto_rawDescOnce sync.Once
file_pkg_api_api_proto_rawDescData = file_pkg_api_api_proto_rawDesc
)
func file_pkg_api_api_proto_rawDescGZIP() []byte {
file_pkg_api_api_proto_rawDescOnce.Do(func() {
file_pkg_api_api_proto_rawDescData = protoimpl.X.CompressGZIP(file_pkg_api_api_proto_rawDescData)
})
return file_pkg_api_api_proto_rawDescData
}
var file_pkg_api_api_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_pkg_api_api_proto_msgTypes = make([]protoimpl.MessageInfo, 50)
var file_pkg_api_api_proto_goTypes = []interface{}{
(Event)(0), // 0: nri.pkg.api.v1alpha1.Event
(ContainerState)(0), // 1: nri.pkg.api.v1alpha1.ContainerState
(*RegisterPluginRequest)(nil), // 2: nri.pkg.api.v1alpha1.RegisterPluginRequest
(*UpdateContainersRequest)(nil), // 3: nri.pkg.api.v1alpha1.UpdateContainersRequest
(*UpdateContainersResponse)(nil), // 4: nri.pkg.api.v1alpha1.UpdateContainersResponse
(*ConfigureRequest)(nil), // 5: nri.pkg.api.v1alpha1.ConfigureRequest
(*ConfigureResponse)(nil), // 6: nri.pkg.api.v1alpha1.ConfigureResponse
(*SynchronizeRequest)(nil), // 7: nri.pkg.api.v1alpha1.SynchronizeRequest
(*SynchronizeResponse)(nil), // 8: nri.pkg.api.v1alpha1.SynchronizeResponse
(*CreateContainerRequest)(nil), // 9: nri.pkg.api.v1alpha1.CreateContainerRequest
(*CreateContainerResponse)(nil), // 10: nri.pkg.api.v1alpha1.CreateContainerResponse
(*UpdateContainerRequest)(nil), // 11: nri.pkg.api.v1alpha1.UpdateContainerRequest
(*UpdateContainerResponse)(nil), // 12: nri.pkg.api.v1alpha1.UpdateContainerResponse
(*StopContainerRequest)(nil), // 13: nri.pkg.api.v1alpha1.StopContainerRequest
(*StopContainerResponse)(nil), // 14: nri.pkg.api.v1alpha1.StopContainerResponse
(*StateChangeEvent)(nil), // 15: nri.pkg.api.v1alpha1.StateChangeEvent
(*Empty)(nil), // 16: nri.pkg.api.v1alpha1.Empty
(*PodSandbox)(nil), // 17: nri.pkg.api.v1alpha1.PodSandbox
(*LinuxPodSandbox)(nil), // 18: nri.pkg.api.v1alpha1.LinuxPodSandbox
(*Container)(nil), // 19: nri.pkg.api.v1alpha1.Container
(*Mount)(nil), // 20: nri.pkg.api.v1alpha1.Mount
(*Hooks)(nil), // 21: nri.pkg.api.v1alpha1.Hooks
(*Hook)(nil), // 22: nri.pkg.api.v1alpha1.Hook
(*LinuxContainer)(nil), // 23: nri.pkg.api.v1alpha1.LinuxContainer
(*LinuxNamespace)(nil), // 24: nri.pkg.api.v1alpha1.LinuxNamespace
(*LinuxDevice)(nil), // 25: nri.pkg.api.v1alpha1.LinuxDevice
(*LinuxDeviceCgroup)(nil), // 26: nri.pkg.api.v1alpha1.LinuxDeviceCgroup
(*LinuxResources)(nil), // 27: nri.pkg.api.v1alpha1.LinuxResources
(*LinuxMemory)(nil), // 28: nri.pkg.api.v1alpha1.LinuxMemory
(*LinuxCPU)(nil), // 29: nri.pkg.api.v1alpha1.LinuxCPU
(*HugepageLimit)(nil), // 30: nri.pkg.api.v1alpha1.HugepageLimit
(*POSIXRlimit)(nil), // 31: nri.pkg.api.v1alpha1.POSIXRlimit
(*ContainerAdjustment)(nil), // 32: nri.pkg.api.v1alpha1.ContainerAdjustment
(*LinuxContainerAdjustment)(nil), // 33: nri.pkg.api.v1alpha1.LinuxContainerAdjustment
(*ContainerUpdate)(nil), // 34: nri.pkg.api.v1alpha1.ContainerUpdate
(*LinuxContainerUpdate)(nil), // 35: nri.pkg.api.v1alpha1.LinuxContainerUpdate
(*ContainerEviction)(nil), // 36: nri.pkg.api.v1alpha1.ContainerEviction
(*KeyValue)(nil), // 37: nri.pkg.api.v1alpha1.KeyValue
(*OptionalString)(nil), // 38: nri.pkg.api.v1alpha1.OptionalString
(*OptionalInt)(nil), // 39: nri.pkg.api.v1alpha1.OptionalInt
(*OptionalInt32)(nil), // 40: nri.pkg.api.v1alpha1.OptionalInt32
(*OptionalUInt32)(nil), // 41: nri.pkg.api.v1alpha1.OptionalUInt32
(*OptionalInt64)(nil), // 42: nri.pkg.api.v1alpha1.OptionalInt64
(*OptionalUInt64)(nil), // 43: nri.pkg.api.v1alpha1.OptionalUInt64
(*OptionalBool)(nil), // 44: nri.pkg.api.v1alpha1.OptionalBool
(*OptionalFileMode)(nil), // 45: nri.pkg.api.v1alpha1.OptionalFileMode
nil, // 46: nri.pkg.api.v1alpha1.PodSandbox.LabelsEntry
nil, // 47: nri.pkg.api.v1alpha1.PodSandbox.AnnotationsEntry
nil, // 48: nri.pkg.api.v1alpha1.Container.LabelsEntry
nil, // 49: nri.pkg.api.v1alpha1.Container.AnnotationsEntry
nil, // 50: nri.pkg.api.v1alpha1.LinuxResources.UnifiedEntry
nil, // 51: nri.pkg.api.v1alpha1.ContainerAdjustment.AnnotationsEntry
}
var file_pkg_api_api_proto_depIdxs = []int32{
34, // 0: nri.pkg.api.v1alpha1.UpdateContainersRequest.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate
36, // 1: nri.pkg.api.v1alpha1.UpdateContainersRequest.evict:type_name -> nri.pkg.api.v1alpha1.ContainerEviction
34, // 2: nri.pkg.api.v1alpha1.UpdateContainersResponse.failed:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate
17, // 3: nri.pkg.api.v1alpha1.SynchronizeRequest.pods:type_name -> nri.pkg.api.v1alpha1.PodSandbox
19, // 4: nri.pkg.api.v1alpha1.SynchronizeRequest.containers:type_name -> nri.pkg.api.v1alpha1.Container
34, // 5: nri.pkg.api.v1alpha1.SynchronizeResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate
17, // 6: nri.pkg.api.v1alpha1.CreateContainerRequest.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox
19, // 7: nri.pkg.api.v1alpha1.CreateContainerRequest.container:type_name -> nri.pkg.api.v1alpha1.Container
32, // 8: nri.pkg.api.v1alpha1.CreateContainerResponse.adjust:type_name -> nri.pkg.api.v1alpha1.ContainerAdjustment
34, // 9: nri.pkg.api.v1alpha1.CreateContainerResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate
36, // 10: nri.pkg.api.v1alpha1.CreateContainerResponse.evict:type_name -> nri.pkg.api.v1alpha1.ContainerEviction
17, // 11: nri.pkg.api.v1alpha1.UpdateContainerRequest.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox
19, // 12: nri.pkg.api.v1alpha1.UpdateContainerRequest.container:type_name -> nri.pkg.api.v1alpha1.Container
27, // 13: nri.pkg.api.v1alpha1.UpdateContainerRequest.linux_resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources
34, // 14: nri.pkg.api.v1alpha1.UpdateContainerResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate
36, // 15: nri.pkg.api.v1alpha1.UpdateContainerResponse.evict:type_name -> nri.pkg.api.v1alpha1.ContainerEviction
17, // 16: nri.pkg.api.v1alpha1.StopContainerRequest.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox
19, // 17: nri.pkg.api.v1alpha1.StopContainerRequest.container:type_name -> nri.pkg.api.v1alpha1.Container
34, // 18: nri.pkg.api.v1alpha1.StopContainerResponse.update:type_name -> nri.pkg.api.v1alpha1.ContainerUpdate
0, // 19: nri.pkg.api.v1alpha1.StateChangeEvent.event:type_name -> nri.pkg.api.v1alpha1.Event
17, // 20: nri.pkg.api.v1alpha1.StateChangeEvent.pod:type_name -> nri.pkg.api.v1alpha1.PodSandbox
19, // 21: nri.pkg.api.v1alpha1.StateChangeEvent.container:type_name -> nri.pkg.api.v1alpha1.Container
46, // 22: nri.pkg.api.v1alpha1.PodSandbox.labels:type_name -> nri.pkg.api.v1alpha1.PodSandbox.LabelsEntry
47, // 23: nri.pkg.api.v1alpha1.PodSandbox.annotations:type_name -> nri.pkg.api.v1alpha1.PodSandbox.AnnotationsEntry
18, // 24: nri.pkg.api.v1alpha1.PodSandbox.linux:type_name -> nri.pkg.api.v1alpha1.LinuxPodSandbox
27, // 25: nri.pkg.api.v1alpha1.LinuxPodSandbox.pod_overhead:type_name -> nri.pkg.api.v1alpha1.LinuxResources
27, // 26: nri.pkg.api.v1alpha1.LinuxPodSandbox.pod_resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources
24, // 27: nri.pkg.api.v1alpha1.LinuxPodSandbox.namespaces:type_name -> nri.pkg.api.v1alpha1.LinuxNamespace
27, // 28: nri.pkg.api.v1alpha1.LinuxPodSandbox.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources
1, // 29: nri.pkg.api.v1alpha1.Container.state:type_name -> nri.pkg.api.v1alpha1.ContainerState
48, // 30: nri.pkg.api.v1alpha1.Container.labels:type_name -> nri.pkg.api.v1alpha1.Container.LabelsEntry
49, // 31: nri.pkg.api.v1alpha1.Container.annotations:type_name -> nri.pkg.api.v1alpha1.Container.AnnotationsEntry
20, // 32: nri.pkg.api.v1alpha1.Container.mounts:type_name -> nri.pkg.api.v1alpha1.Mount
21, // 33: nri.pkg.api.v1alpha1.Container.hooks:type_name -> nri.pkg.api.v1alpha1.Hooks
23, // 34: nri.pkg.api.v1alpha1.Container.linux:type_name -> nri.pkg.api.v1alpha1.LinuxContainer
31, // 35: nri.pkg.api.v1alpha1.Container.rlimits:type_name -> nri.pkg.api.v1alpha1.POSIXRlimit
22, // 36: nri.pkg.api.v1alpha1.Hooks.prestart:type_name -> nri.pkg.api.v1alpha1.Hook
22, // 37: nri.pkg.api.v1alpha1.Hooks.create_runtime:type_name -> nri.pkg.api.v1alpha1.Hook
22, // 38: nri.pkg.api.v1alpha1.Hooks.create_container:type_name -> nri.pkg.api.v1alpha1.Hook
22, // 39: nri.pkg.api.v1alpha1.Hooks.start_container:type_name -> nri.pkg.api.v1alpha1.Hook
22, // 40: nri.pkg.api.v1alpha1.Hooks.poststart:type_name -> nri.pkg.api.v1alpha1.Hook
22, // 41: nri.pkg.api.v1alpha1.Hooks.poststop:type_name -> nri.pkg.api.v1alpha1.Hook
39, // 42: nri.pkg.api.v1alpha1.Hook.timeout:type_name -> nri.pkg.api.v1alpha1.OptionalInt
24, // 43: nri.pkg.api.v1alpha1.LinuxContainer.namespaces:type_name -> nri.pkg.api.v1alpha1.LinuxNamespace
25, // 44: nri.pkg.api.v1alpha1.LinuxContainer.devices:type_name -> nri.pkg.api.v1alpha1.LinuxDevice
27, // 45: nri.pkg.api.v1alpha1.LinuxContainer.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources
39, // 46: nri.pkg.api.v1alpha1.LinuxContainer.oom_score_adj:type_name -> nri.pkg.api.v1alpha1.OptionalInt
45, // 47: nri.pkg.api.v1alpha1.LinuxDevice.file_mode:type_name -> nri.pkg.api.v1alpha1.OptionalFileMode
41, // 48: nri.pkg.api.v1alpha1.LinuxDevice.uid:type_name -> nri.pkg.api.v1alpha1.OptionalUInt32
41, // 49: nri.pkg.api.v1alpha1.LinuxDevice.gid:type_name -> nri.pkg.api.v1alpha1.OptionalUInt32
42, // 50: nri.pkg.api.v1alpha1.LinuxDeviceCgroup.major:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
42, // 51: nri.pkg.api.v1alpha1.LinuxDeviceCgroup.minor:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
28, // 52: nri.pkg.api.v1alpha1.LinuxResources.memory:type_name -> nri.pkg.api.v1alpha1.LinuxMemory
29, // 53: nri.pkg.api.v1alpha1.LinuxResources.cpu:type_name -> nri.pkg.api.v1alpha1.LinuxCPU
30, // 54: nri.pkg.api.v1alpha1.LinuxResources.hugepage_limits:type_name -> nri.pkg.api.v1alpha1.HugepageLimit
38, // 55: nri.pkg.api.v1alpha1.LinuxResources.blockio_class:type_name -> nri.pkg.api.v1alpha1.OptionalString
38, // 56: nri.pkg.api.v1alpha1.LinuxResources.rdt_class:type_name -> nri.pkg.api.v1alpha1.OptionalString
50, // 57: nri.pkg.api.v1alpha1.LinuxResources.unified:type_name -> nri.pkg.api.v1alpha1.LinuxResources.UnifiedEntry
26, // 58: nri.pkg.api.v1alpha1.LinuxResources.devices:type_name -> nri.pkg.api.v1alpha1.LinuxDeviceCgroup
42, // 59: nri.pkg.api.v1alpha1.LinuxMemory.limit:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
42, // 60: nri.pkg.api.v1alpha1.LinuxMemory.reservation:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
42, // 61: nri.pkg.api.v1alpha1.LinuxMemory.swap:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
42, // 62: nri.pkg.api.v1alpha1.LinuxMemory.kernel:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
42, // 63: nri.pkg.api.v1alpha1.LinuxMemory.kernel_tcp:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
43, // 64: nri.pkg.api.v1alpha1.LinuxMemory.swappiness:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64
44, // 65: nri.pkg.api.v1alpha1.LinuxMemory.disable_oom_killer:type_name -> nri.pkg.api.v1alpha1.OptionalBool
44, // 66: nri.pkg.api.v1alpha1.LinuxMemory.use_hierarchy:type_name -> nri.pkg.api.v1alpha1.OptionalBool
43, // 67: nri.pkg.api.v1alpha1.LinuxCPU.shares:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64
42, // 68: nri.pkg.api.v1alpha1.LinuxCPU.quota:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
43, // 69: nri.pkg.api.v1alpha1.LinuxCPU.period:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64
42, // 70: nri.pkg.api.v1alpha1.LinuxCPU.realtime_runtime:type_name -> nri.pkg.api.v1alpha1.OptionalInt64
43, // 71: nri.pkg.api.v1alpha1.LinuxCPU.realtime_period:type_name -> nri.pkg.api.v1alpha1.OptionalUInt64
51, // 72: nri.pkg.api.v1alpha1.ContainerAdjustment.annotations:type_name -> nri.pkg.api.v1alpha1.ContainerAdjustment.AnnotationsEntry
20, // 73: nri.pkg.api.v1alpha1.ContainerAdjustment.mounts:type_name -> nri.pkg.api.v1alpha1.Mount
37, // 74: nri.pkg.api.v1alpha1.ContainerAdjustment.env:type_name -> nri.pkg.api.v1alpha1.KeyValue
21, // 75: nri.pkg.api.v1alpha1.ContainerAdjustment.hooks:type_name -> nri.pkg.api.v1alpha1.Hooks
33, // 76: nri.pkg.api.v1alpha1.ContainerAdjustment.linux:type_name -> nri.pkg.api.v1alpha1.LinuxContainerAdjustment
31, // 77: nri.pkg.api.v1alpha1.ContainerAdjustment.rlimits:type_name -> nri.pkg.api.v1alpha1.POSIXRlimit
25, // 78: nri.pkg.api.v1alpha1.LinuxContainerAdjustment.devices:type_name -> nri.pkg.api.v1alpha1.LinuxDevice
27, // 79: nri.pkg.api.v1alpha1.LinuxContainerAdjustment.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources
35, // 80: nri.pkg.api.v1alpha1.ContainerUpdate.linux:type_name -> nri.pkg.api.v1alpha1.LinuxContainerUpdate
27, // 81: nri.pkg.api.v1alpha1.LinuxContainerUpdate.resources:type_name -> nri.pkg.api.v1alpha1.LinuxResources
2, // 82: nri.pkg.api.v1alpha1.Runtime.RegisterPlugin:input_type -> nri.pkg.api.v1alpha1.RegisterPluginRequest
3, // 83: nri.pkg.api.v1alpha1.Runtime.UpdateContainers:input_type -> nri.pkg.api.v1alpha1.UpdateContainersRequest
5, // 84: nri.pkg.api.v1alpha1.Plugin.Configure:input_type -> nri.pkg.api.v1alpha1.ConfigureRequest
7, // 85: nri.pkg.api.v1alpha1.Plugin.Synchronize:input_type -> nri.pkg.api.v1alpha1.SynchronizeRequest
16, // 86: nri.pkg.api.v1alpha1.Plugin.Shutdown:input_type -> nri.pkg.api.v1alpha1.Empty
9, // 87: nri.pkg.api.v1alpha1.Plugin.CreateContainer:input_type -> nri.pkg.api.v1alpha1.CreateContainerRequest
11, // 88: nri.pkg.api.v1alpha1.Plugin.UpdateContainer:input_type -> nri.pkg.api.v1alpha1.UpdateContainerRequest
13, // 89: nri.pkg.api.v1alpha1.Plugin.StopContainer:input_type -> nri.pkg.api.v1alpha1.StopContainerRequest
15, // 90: nri.pkg.api.v1alpha1.Plugin.StateChange:input_type -> nri.pkg.api.v1alpha1.StateChangeEvent
16, // 91: nri.pkg.api.v1alpha1.Runtime.RegisterPlugin:output_type -> nri.pkg.api.v1alpha1.Empty
4, // 92: nri.pkg.api.v1alpha1.Runtime.UpdateContainers:output_type -> nri.pkg.api.v1alpha1.UpdateContainersResponse
6, // 93: nri.pkg.api.v1alpha1.Plugin.Configure:output_type -> nri.pkg.api.v1alpha1.ConfigureResponse
8, // 94: nri.pkg.api.v1alpha1.Plugin.Synchronize:output_type -> nri.pkg.api.v1alpha1.SynchronizeResponse
16, // 95: nri.pkg.api.v1alpha1.Plugin.Shutdown:output_type -> nri.pkg.api.v1alpha1.Empty
10, // 96: nri.pkg.api.v1alpha1.Plugin.CreateContainer:output_type -> nri.pkg.api.v1alpha1.CreateContainerResponse
12, // 97: nri.pkg.api.v1alpha1.Plugin.UpdateContainer:output_type -> nri.pkg.api.v1alpha1.UpdateContainerResponse
14, // 98: nri.pkg.api.v1alpha1.Plugin.StopContainer:output_type -> nri.pkg.api.v1alpha1.StopContainerResponse
16, // 99: nri.pkg.api.v1alpha1.Plugin.StateChange:output_type -> nri.pkg.api.v1alpha1.Empty
91, // [91:100] is the sub-list for method output_type
82, // [82:91] is the sub-list for method input_type
82, // [82:82] is the sub-list for extension type_name
82, // [82:82] is the sub-list for extension extendee
0, // [0:82] is the sub-list for field type_name
}
func init() { file_pkg_api_api_proto_init() }
func file_pkg_api_api_proto_init() {
if File_pkg_api_api_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_pkg_api_api_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegisterPluginRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateContainersRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UpdateContainersResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ConfigureRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ConfigureResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SynchronizeRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*SynchronizeResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[7].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_pkg_api_api_proto_msgTypes[8].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_pkg_api_api_proto_msgTypes[9].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_pkg_api_api_proto_msgTypes[10].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_pkg_api_api_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StopContainerRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StopContainerResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StateChangeEvent); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Empty); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*PodSandbox); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxPodSandbox); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[17].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_pkg_api_api_proto_msgTypes[18].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
}
}
file_pkg_api_api_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Hooks); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Hook); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxContainer); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxNamespace); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxDevice); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxDeviceCgroup); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxResources); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxMemory); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxCPU); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*HugepageLimit); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*POSIXRlimit); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ContainerAdjustment); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxContainerAdjustment); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ContainerUpdate); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LinuxContainerUpdate); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ContainerEviction); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[35].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
}
}
file_pkg_api_api_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalString); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalInt); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalInt32); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[39].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalUInt32); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[40].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalInt64); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[41].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalUInt64); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[42].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalBool); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_pkg_api_api_proto_msgTypes[43].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*OptionalFileMode); 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_pkg_api_api_proto_rawDesc,
NumEnums: 2,
NumMessages: 50,
NumExtensions: 0,
NumServices: 2,
},
GoTypes: file_pkg_api_api_proto_goTypes,
DependencyIndexes: file_pkg_api_api_proto_depIdxs,
EnumInfos: file_pkg_api_api_proto_enumTypes,
MessageInfos: file_pkg_api_api_proto_msgTypes,
}.Build()
File_pkg_api_api_proto = out.File
file_pkg_api_api_proto_rawDesc = nil
file_pkg_api_api_proto_goTypes = nil
file_pkg_api_api_proto_depIdxs = nil
}
nri-0.6.1/pkg/api/api.proto 0000664 0000000 0000000 00000031011 14610311645 0015473 0 ustar 00root root 0000000 0000000 /*
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 nri.pkg.api.v1alpha1;
option go_package = "github.com/containerd/nri/pkg/api;api";
// Runtime service is the public API runtimes expose for NRI plugins.
// On this interface RPC requests are initiated by the plugin. This
// only covers plugin registration and unsolicited container updates.
// The rest of the API is defined by the Plugin service.
service Runtime {
// RegisterPlugin registers the plugin with the runtime.
rpc RegisterPlugin(RegisterPluginRequest) returns (Empty);
// UpdateContainers requests unsolicited updates to a set of containers.
rpc UpdateContainers(UpdateContainersRequest) returns (UpdateContainersResponse);
}
message RegisterPluginRequest {
// Name of the plugin to register.
string plugin_name = 1;
// Plugin invocation index. Plugins are called in ascending index order.
string plugin_idx = 2;
}
message UpdateContainersRequest {
// List of containers to update.
repeated ContainerUpdate update = 1;
// List of containers to evict.
repeated ContainerEviction evict = 2;
}
message UpdateContainersResponse {
// Containers that the runtime failed to udpate.
repeated ContainerUpdate failed = 1;
}
//
// Plugin is the API NRI uses to interact with plugins. It is used to
// - configure a plugin and subscribe it for lifecycle events
// - synchronize the state of a plugin with that of the runtime
// - hook a plugin into the lifecycle events of its interest
//
// During configuration the plugin tells the runtime which lifecycle events
// it wishes to get hooked into. Once configured, the plugin is synchronized
// with the runtime by receiving the list of pods and containers known to
// the runtime. The plugin can request changes to any of the containers in
// response. After initial synchronization the plugin starts receiving the
// events it subscribed for as they occur in the runtime. For container
// creation, update, and stop events, the plugin can request changes, both
// to the container that triggered the event or any other existing container
// in the runtime.
//
// For a subset of the container lifecycle events, NRI defines an additional
// Post-variant of the event. These variants are defined for CreateContainer,
// StartContainer, and UpdateContainer. For creation and update, these events
// can be used by plugins to discover the full extent of changes applied to
// the container, including any changes made by other active plugins.
//
service Plugin {
// Configure the plugin and get its event subscription.
rpc Configure(ConfigureRequest) returns (ConfigureResponse);
// Synchronize the plugin with the state of the runtime.
rpc Synchronize(SynchronizeRequest) returns (SynchronizeResponse);
// Shutdown a plugin (let it know the runtime is going down).
rpc Shutdown(Empty) returns (Empty);
// CreateContainer relays the corresponding request to the plugin. In
// response, the plugin can adjust the container being created, and
// update other containers in the runtime. Container adjustment can
// alter labels, annotations, mounts, devices, environment variables,
// OCI hooks, and assigned container resources. Updates can alter
// assigned container resources.
rpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse);
// UpdateContainer relays the corresponding request to the plugin.
// The plugin can alter how the container is updated and request updates
// to additional containers in the runtime.
rpc UpdateContainer(UpdateContainerRequest) returns (UpdateContainerResponse);
// StopContainer relays the corresponding request to the plugin. The plugin
// can update any of the remaining containers in the runtime in response.
rpc StopContainer(StopContainerRequest) returns (StopContainerResponse);
// StateChange relays any remaining pod or container lifecycle/state change
// events the plugin has subscribed for. These can be used to trigger any
// plugin-specific processing which needs to occur in connection with any of
// these events.
rpc StateChange(StateChangeEvent) returns (Empty);
}
message ConfigureRequest {
// Any plugin-specific data, if present among the NRI configuration.
string config = 1;
// Name of the runtime NRI is running in.
string runtime_name = 2;
// Version of the runtime NRI is running in.
string runtime_version = 3;
}
message ConfigureResponse {
// Events to subscribe the plugin for. Each bit set corresponds to an
// enumerated Event.
int32 events = 2;
}
message SynchronizeRequest {
// Pods known to the runtime.
repeated PodSandbox pods = 1;
// Containers known to the runtime.
repeated Container containers = 2;
}
message SynchronizeResponse {
// Updates to containers requested by the plugin.
repeated ContainerUpdate update = 1;
}
message CreateContainerRequest {
// Pod of container being created.
PodSandbox pod = 1;
// Container being created.
Container container = 2;
}
message CreateContainerResponse {
// Requested adjustments to container being created.
ContainerAdjustment adjust = 1;
// Requested updates to other existing containers.
repeated ContainerUpdate update = 2;
// Requested eviction of existing containers.
repeated ContainerEviction evict = 3;
}
message UpdateContainerRequest {
// Pod of container being updated.
PodSandbox pod = 1;
// Container being updated.
Container container = 2;
// Resources to update.
LinuxResources linux_resources = 3;
}
message UpdateContainerResponse {
// Requested updates to containers.
repeated ContainerUpdate update = 1;
// Requested eviction of containers.
repeated ContainerEviction evict = 2;
}
message StopContainerRequest {
// Pod of container being stopped.
PodSandbox pod = 1;
// Container being stopped.
Container container = 2;
}
message StopContainerResponse {
// Requested updates to containers.
repeated ContainerUpdate update = 1;
}
message StateChangeEvent {
// Event type of notification.
Event event = 1;
// Pod this notification is sent for. If this event is related to a container,
// pod is set to the pod of the container.
PodSandbox pod = 2;
// Container this notification is sent for. If the event is related to a pod,
// container is nil.
Container container = 3;
}
// Empty response for those *Requests that are semantically events.
message Empty {}
// Events that plugins can subscribe to in ConfigureResponse.
enum Event {
UNKNOWN = 0;
RUN_POD_SANDBOX = 1;
STOP_POD_SANDBOX = 2;
REMOVE_POD_SANDBOX = 3;
CREATE_CONTAINER = 4;
POST_CREATE_CONTAINER = 5;
START_CONTAINER = 6;
POST_START_CONTAINER = 7;
UPDATE_CONTAINER = 8;
POST_UPDATE_CONTAINER = 9;
STOP_CONTAINER = 10;
REMOVE_CONTAINER = 11;
LAST = 12;
}
// Pod metadata that is considered relevant for a plugin.
message PodSandbox {
string id = 1;
string name = 2;
string uid = 3;
string namespace = 4;
map labels = 5;
map annotations = 6;
string runtime_handler = 7;
LinuxPodSandbox linux = 8;
uint32 pid = 9; // for NRI v1 emulation
}
// PodSandbox linux-specific metadata
message LinuxPodSandbox {
LinuxResources pod_overhead = 1;
LinuxResources pod_resources = 2;
string cgroup_parent = 3;
string cgroups_path = 4; // for NRI v1 emulation
repeated LinuxNamespace namespaces = 5; // for NRI v1 emulation
LinuxResources resources = 6; // for NRI v1 emulation
}
// Container metadata that is considered relevant for a plugin.
message Container {
string id = 1;
string pod_sandbox_id = 2;
string name = 3;
ContainerState state = 4;
map labels = 5;
map annotations = 6;
repeated string args = 7;
repeated string env = 8;
repeated Mount mounts = 9;
Hooks hooks = 10;
LinuxContainer linux = 11;
uint32 pid = 12; // for NRI v1 emulation
repeated POSIXRlimit rlimits = 13;
}
// Possible container states.
enum ContainerState {
CONTAINER_UNKNOWN = 0;
CONTAINER_CREATED = 1;
CONTAINER_PAUSED = 2; // is this useful/necessary ?
CONTAINER_RUNNING = 3;
CONTAINER_STOPPED = 4;
}
// A container mount.
message Mount {
string destination = 1;
string type = 2;
string source = 3;
repeated string options = 4;
}
// Container OCI hooks.
message Hooks {
repeated Hook prestart = 1;
repeated Hook create_runtime = 2;
repeated Hook create_container = 3;
repeated Hook start_container = 4;
repeated Hook poststart = 5;
repeated Hook poststop = 6;
}
// One OCI hook.
message Hook {
string path = 1;
repeated string args = 2;
repeated string env = 3;
OptionalInt timeout = 4;
}
// Container (linux) metadata.
message LinuxContainer {
repeated LinuxNamespace namespaces = 1;
repeated LinuxDevice devices = 2;
LinuxResources resources = 3;
OptionalInt oom_score_adj = 4;
string cgroups_path = 5;
}
// A linux namespace.
message LinuxNamespace {
string type = 1;
string path = 2;
}
// A container (linux) device.
message LinuxDevice {
string path = 1;
string type = 2;
int64 major = 3;
int64 minor = 4;
OptionalFileMode file_mode = 5;
OptionalUInt32 uid = 6;
OptionalUInt32 gid = 7;
}
// A linux device cgroup controller rule.
message LinuxDeviceCgroup {
bool allow = 1;
string type = 2;
OptionalInt64 major = 3;
OptionalInt64 minor = 4;
string access = 5;
}
// Container (linux) resources.
message LinuxResources {
LinuxMemory memory = 1;
LinuxCPU cpu = 2;
repeated HugepageLimit hugepage_limits = 3;
OptionalString blockio_class = 4;
OptionalString rdt_class = 5;
map unified = 6;
repeated LinuxDeviceCgroup devices = 7; // for NRI v1 emulation
}
// Memory-related parts of (linux) resources.
message LinuxMemory {
OptionalInt64 limit = 1;
OptionalInt64 reservation = 2;
OptionalInt64 swap = 3;
OptionalInt64 kernel = 4;
OptionalInt64 kernel_tcp = 5;
OptionalUInt64 swappiness = 6;
OptionalBool disable_oom_killer = 7;
OptionalBool use_hierarchy = 8;
}
// CPU-related parts of (linux) resources.
message LinuxCPU {
OptionalUInt64 shares = 1;
OptionalInt64 quota = 2;
OptionalUInt64 period = 3;
OptionalInt64 realtime_runtime = 4;
OptionalUInt64 realtime_period = 5;
string cpus = 6;
string mems = 7;
}
// Container huge page limit.
message HugepageLimit {
string page_size = 1;
uint64 limit = 2;
}
// Container rlimits
message POSIXRlimit {
string type = 1;
uint64 hard = 2;
uint64 soft = 3;
}
// Requested adjustments to a container being created.
message ContainerAdjustment {
map annotations = 2;
repeated Mount mounts = 3;
repeated KeyValue env = 4;
Hooks hooks = 5;
LinuxContainerAdjustment linux = 6;
repeated POSIXRlimit rlimits = 7;
}
// Adjustments to (linux) resources.
message LinuxContainerAdjustment {
repeated LinuxDevice devices = 1;
LinuxResources resources = 2;
string cgroups_path = 3;
}
// Requested update to an already created container.
message ContainerUpdate {
string container_id = 1;
LinuxContainerUpdate linux = 2;
bool ignore_failure = 3;
}
// Updates to (linux) resources.
message LinuxContainerUpdate {
LinuxResources resources = 1;
}
// Request to evict (IOW unsolicitedly stop) a container.
message ContainerEviction {
// Container to evict.
string container_id = 1;
// Human-readable reason for eviction.
string reason = 2;
}
// KeyValue represents an environment variable.
message KeyValue {
string key = 1;
string value = 2;
}
// An optional string value.
message OptionalString {
string value = 1;
}
// An optional signed integer value.
message OptionalInt {
int64 value = 1;
}
// An optional 32-bit signed integer value.
message OptionalInt32 {
int32 value = 1;
}
// An optional 32-bit unsigned integer value.
message OptionalUInt32 {
uint32 value = 1;
}
// An optional 64-bit signed integer value.
message OptionalInt64 {
int64 value = 1;
}
// An optional 64-bit unsigned integer value.
message OptionalUInt64 {
uint64 value = 1;
}
// An optional boolean value.
message OptionalBool {
bool value = 1;
}
// An optional value of file permissions.
message OptionalFileMode {
uint32 value = 1;
}
nri-0.6.1/pkg/api/api_ttrpc.pb.go 0000664 0000000 0000000 00000014504 14610311645 0016561 0 ustar 00root root 0000000 0000000 // Code generated by protoc-gen-go-ttrpc. DO NOT EDIT.
// source: pkg/api/api.proto
package api
import (
context "context"
ttrpc "github.com/containerd/ttrpc"
)
type RuntimeService interface {
RegisterPlugin(context.Context, *RegisterPluginRequest) (*Empty, error)
UpdateContainers(context.Context, *UpdateContainersRequest) (*UpdateContainersResponse, error)
}
func RegisterRuntimeService(srv *ttrpc.Server, svc RuntimeService) {
srv.RegisterService("nri.pkg.api.v1alpha1.Runtime", &ttrpc.ServiceDesc{
Methods: map[string]ttrpc.Method{
"RegisterPlugin": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req RegisterPluginRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.RegisterPlugin(ctx, &req)
},
"UpdateContainers": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req UpdateContainersRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.UpdateContainers(ctx, &req)
},
},
})
}
type runtimeClient struct {
client *ttrpc.Client
}
func NewRuntimeClient(client *ttrpc.Client) RuntimeService {
return &runtimeClient{
client: client,
}
}
func (c *runtimeClient) RegisterPlugin(ctx context.Context, req *RegisterPluginRequest) (*Empty, error) {
var resp Empty
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Runtime", "RegisterPlugin", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
func (c *runtimeClient) UpdateContainers(ctx context.Context, req *UpdateContainersRequest) (*UpdateContainersResponse, error) {
var resp UpdateContainersResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Runtime", "UpdateContainers", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
type PluginService interface {
Configure(context.Context, *ConfigureRequest) (*ConfigureResponse, error)
Synchronize(context.Context, *SynchronizeRequest) (*SynchronizeResponse, error)
Shutdown(context.Context, *Empty) (*Empty, error)
CreateContainer(context.Context, *CreateContainerRequest) (*CreateContainerResponse, error)
UpdateContainer(context.Context, *UpdateContainerRequest) (*UpdateContainerResponse, error)
StopContainer(context.Context, *StopContainerRequest) (*StopContainerResponse, error)
StateChange(context.Context, *StateChangeEvent) (*Empty, error)
}
func RegisterPluginService(srv *ttrpc.Server, svc PluginService) {
srv.RegisterService("nri.pkg.api.v1alpha1.Plugin", &ttrpc.ServiceDesc{
Methods: map[string]ttrpc.Method{
"Configure": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req ConfigureRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Configure(ctx, &req)
},
"Synchronize": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req SynchronizeRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Synchronize(ctx, &req)
},
"Shutdown": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req Empty
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.Shutdown(ctx, &req)
},
"CreateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req CreateContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.CreateContainer(ctx, &req)
},
"UpdateContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req UpdateContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.UpdateContainer(ctx, &req)
},
"StopContainer": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req StopContainerRequest
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.StopContainer(ctx, &req)
},
"StateChange": func(ctx context.Context, unmarshal func(interface{}) error) (interface{}, error) {
var req StateChangeEvent
if err := unmarshal(&req); err != nil {
return nil, err
}
return svc.StateChange(ctx, &req)
},
},
})
}
type pluginClient struct {
client *ttrpc.Client
}
func NewPluginClient(client *ttrpc.Client) PluginService {
return &pluginClient{
client: client,
}
}
func (c *pluginClient) Configure(ctx context.Context, req *ConfigureRequest) (*ConfigureResponse, error) {
var resp ConfigureResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Configure", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
func (c *pluginClient) Synchronize(ctx context.Context, req *SynchronizeRequest) (*SynchronizeResponse, error) {
var resp SynchronizeResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Synchronize", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
func (c *pluginClient) Shutdown(ctx context.Context, req *Empty) (*Empty, error) {
var resp Empty
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "Shutdown", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
func (c *pluginClient) CreateContainer(ctx context.Context, req *CreateContainerRequest) (*CreateContainerResponse, error) {
var resp CreateContainerResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "CreateContainer", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
func (c *pluginClient) UpdateContainer(ctx context.Context, req *UpdateContainerRequest) (*UpdateContainerResponse, error) {
var resp UpdateContainerResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "UpdateContainer", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
func (c *pluginClient) StopContainer(ctx context.Context, req *StopContainerRequest) (*StopContainerResponse, error) {
var resp StopContainerResponse
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "StopContainer", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
func (c *pluginClient) StateChange(ctx context.Context, req *StateChangeEvent) (*Empty, error) {
var resp Empty
if err := c.client.Call(ctx, "nri.pkg.api.v1alpha1.Plugin", "StateChange", req, &resp); err != nil {
return nil, err
}
return &resp, nil
}
nri-0.6.1/pkg/api/device.go 0000664 0000000 0000000 00000004202 14610311645 0015425 0 ustar 00root root 0000000 0000000 /*
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 api
import (
rspec "github.com/opencontainers/runtime-spec/specs-go"
)
// FromOCILinuxDevices returns a device slice from an OCI runtime Spec.
func FromOCILinuxDevices(o []rspec.LinuxDevice) []*LinuxDevice {
var devices []*LinuxDevice
for _, d := range o {
devices = append(devices, &LinuxDevice{
Path: d.Path,
Type: d.Type,
Major: d.Major,
Minor: d.Minor,
FileMode: FileMode(d.FileMode),
Uid: UInt32(d.UID),
Gid: UInt32(d.GID),
})
}
return devices
}
// ToOCI returns the linux devices for an OCI runtime Spec.
func (d *LinuxDevice) ToOCI() rspec.LinuxDevice {
if d == nil {
return rspec.LinuxDevice{}
}
return rspec.LinuxDevice{
Path: d.Path,
Type: d.Type,
Major: d.Major,
Minor: d.Minor,
FileMode: d.FileMode.Get(),
UID: d.Uid.Get(),
GID: d.Gid.Get(),
}
}
// AccessString returns an OCI access string for the device.
func (d *LinuxDevice) AccessString() string {
r, w, m := "r", "w", ""
if mode := d.FileMode.Get(); mode != nil {
perm := mode.Perm()
if (perm & 0444) != 0 {
r = "r"
}
if (perm & 0222) != 0 {
w = "w"
}
}
if d.Type == "b" {
m = "m"
}
return r + w + m
}
// Cmp returns true if the devices are equal.
func (d *LinuxDevice) Cmp(v *LinuxDevice) bool {
if v == nil {
return false
}
return d.Major != v.Major || d.Minor != v.Minor
}
// IsMarkedForRemoval checks if a LinuxDevice is marked for removal.
func (d *LinuxDevice) IsMarkedForRemoval() (string, bool) {
key, marked := IsMarkedForRemoval(d.Path)
return key, marked
}
nri-0.6.1/pkg/api/doc.go 0000664 0000000 0000000 00000001140 14610311645 0014731 0 ustar 00root root 0000000 0000000 /*
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 api
nri-0.6.1/pkg/api/env.go 0000664 0000000 0000000 00000002674 14610311645 0014771 0 ustar 00root root 0000000 0000000 /*
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 api
import (
"strings"
)
// ToOCI returns an OCI Env entry for the KeyValue.
func (e *KeyValue) ToOCI() string {
return e.Key + "=" + e.Value
}
// FromOCIEnv returns KeyValues from an OCI runtime Spec environment.
func FromOCIEnv(in []string) []*KeyValue {
if in == nil {
return nil
}
out := []*KeyValue{}
for _, keyval := range in {
var key, val string
split := strings.SplitN(keyval, "=", 2)
switch len(split) {
case 0:
continue
case 1:
key = split[0]
case 2:
key = split[0]
val = split[1]
default:
val = strings.Join(split[1:], "=")
}
out = append(out, &KeyValue{
Key: key,
Value: val,
})
}
return out
}
// IsMarkedForRemoval checks if an environment variable is marked for removal.
func (e *KeyValue) IsMarkedForRemoval() (string, bool) {
key, marked := IsMarkedForRemoval(e.Key)
return key, marked
}
nri-0.6.1/pkg/api/event.go 0000664 0000000 0000000 00000011301 14610311645 0015305 0 ustar 00root root 0000000 0000000 /*
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 api
import (
"fmt"
"strings"
)
const (
// ValidEvents is the event mask of all valid events.
ValidEvents = EventMask((1 << (Event_LAST - 1)) - 1)
)
// nolint
type (
// Define *Request/*Response type aliases for *Event/Empty pairs.
StateChangeResponse = Empty
RunPodSandboxRequest = StateChangeEvent
RunPodSandboxResponse = Empty
StopPodSandboxRequest = StateChangeEvent
StopPodSandboxResponse = Empty
RemovePodSandboxRequest = StateChangeEvent
RemovePodSandboxResponse = Empty
StartContainerRequest = StateChangeEvent
StartContainerResponse = Empty
RemoveContainerRequest = StateChangeEvent
RemoveContainerResponse = Empty
PostCreateContainerRequest = StateChangeEvent
PostCreateContainerResponse = Empty
PostStartContainerRequest = StateChangeEvent
PostStartContainerResponse = Empty
PostUpdateContainerRequest = StateChangeEvent
PostUpdateContainerResponse = Empty
ShutdownRequest = Empty
ShutdownResponse = Empty
)
// EventMask corresponds to a set of enumerated Events.
type EventMask int32
// ParseEventMask parses a string representation into an EventMask.
func ParseEventMask(events ...string) (EventMask, error) {
var mask EventMask
bits := map[string]Event{
"runpodsandbox": Event_RUN_POD_SANDBOX,
"stoppodsandbox": Event_STOP_POD_SANDBOX,
"removepodsandbox": Event_REMOVE_POD_SANDBOX,
"createcontainer": Event_CREATE_CONTAINER,
"postcreatecontainer": Event_POST_CREATE_CONTAINER,
"startcontainer": Event_START_CONTAINER,
"poststartcontainer": Event_POST_START_CONTAINER,
"updatecontainer": Event_UPDATE_CONTAINER,
"postupdatecontainer": Event_POST_UPDATE_CONTAINER,
"stopcontainer": Event_STOP_CONTAINER,
"removecontainer": Event_REMOVE_CONTAINER,
}
for _, event := range events {
lcEvents := strings.ToLower(event)
for _, name := range strings.Split(lcEvents, ",") {
switch name {
case "all":
mask |= ValidEvents
continue
case "pod", "podsandbox":
for name, bit := range bits {
if strings.Contains(name, "pod") {
mask.Set(bit)
}
}
continue
case "container":
for name, bit := range bits {
if strings.Contains(name, "container") {
mask.Set(bit)
}
}
continue
}
bit, ok := bits[strings.TrimSpace(name)]
if !ok {
return 0, fmt.Errorf("unknown event %q", name)
}
mask.Set(bit)
}
}
return mask, nil
}
// MustParseEventMask parses the given events, panic()ing on errors.
func MustParseEventMask(events ...string) EventMask {
mask, err := ParseEventMask(events...)
if err != nil {
panic(fmt.Sprintf("failed to parse events %s", strings.Join(events, " ")))
}
return mask
}
// PrettyString returns a human-readable string representation of an EventMask.
func (m *EventMask) PrettyString() string {
names := map[Event]string{
Event_RUN_POD_SANDBOX: "RunPodSandbox",
Event_STOP_POD_SANDBOX: "StopPodSandbox",
Event_REMOVE_POD_SANDBOX: "RemovePodSandbox",
Event_CREATE_CONTAINER: "CreateContainer",
Event_POST_CREATE_CONTAINER: "PostCreateContainer",
Event_START_CONTAINER: "StartContainer",
Event_POST_START_CONTAINER: "PostStartContainer",
Event_UPDATE_CONTAINER: "UpdateContainer",
Event_POST_UPDATE_CONTAINER: "PostUpdateContainer",
Event_STOP_CONTAINER: "StopContainer",
Event_REMOVE_CONTAINER: "RemoveContainer",
}
mask := *m
events, sep := "", ""
for bit := Event_UNKNOWN + 1; bit <= Event_LAST; bit++ {
if mask.IsSet(bit) {
events += sep + names[bit]
sep = ","
mask.Clear(bit)
}
}
if mask != 0 {
events += sep + fmt.Sprintf("unknown(0x%x)", mask)
}
return events
}
// Set sets the given Events in the mask.
func (m *EventMask) Set(events ...Event) *EventMask {
for _, e := range events {
*m |= (1 << (e - 1))
}
return m
}
// Clear clears the given Events in the mask.
func (m *EventMask) Clear(events ...Event) *EventMask {
for _, e := range events {
*m &^= (1 << (e - 1))
}
return m
}
// IsSet check if the given Event is set in the mask.
func (m *EventMask) IsSet(e Event) bool {
return *m&(1<<(e-1)) != 0
}
nri-0.6.1/pkg/api/helpers.go 0000664 0000000 0000000 00000003070 14610311645 0015632 0 ustar 00root root 0000000 0000000 /*
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 api
// DupStringSlice creates a copy of a string slice.
func DupStringSlice(in []string) []string {
if in == nil {
return nil
}
out := make([]string, len(in))
copy(out, in)
return out
}
// DupStringMap creates a copy of a map with string keys and values.
func DupStringMap(in map[string]string) map[string]string {
if in == nil {
return nil
}
out := map[string]string{}
for k, v := range in {
out[k] = v
}
return out
}
// IsMarkedForRemoval checks if a key is marked for removal.
//
// The key can be an annotation name, a mount container path, a device path,
// or an environment variable name. These are all marked for removal in
// adjustments by preceding their corresponding key with a '-'.
func IsMarkedForRemoval(key string) (string, bool) {
if key == "" {
return "", false
}
if key[0] != '-' {
return key, false
}
return key[1:], true
}
// MarkForRemoval returns a key marked for removal.
func MarkForRemoval(key string) string {
return "-" + key
}
nri-0.6.1/pkg/api/hooks.go 0000664 0000000 0000000 00000005243 14610311645 0015317 0 ustar 00root root 0000000 0000000 /*
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 api
import (
rspec "github.com/opencontainers/runtime-spec/specs-go"
)
// Append appends the given hooks to the existing ones.
func (hooks *Hooks) Append(h *Hooks) *Hooks {
if h == nil {
return hooks
}
hooks.Prestart = append(hooks.Prestart, h.Prestart...)
hooks.CreateRuntime = append(hooks.CreateRuntime, h.CreateRuntime...)
hooks.CreateContainer = append(hooks.CreateContainer, h.CreateContainer...)
hooks.StartContainer = append(hooks.StartContainer, h.StartContainer...)
hooks.Poststart = append(hooks.Poststart, h.Poststart...)
hooks.Poststop = append(hooks.Poststop, h.Poststop...)
return hooks
}
// Hooks returns itself it any of its hooks is set. Otherwise it returns nil.
func (hooks *Hooks) Hooks() *Hooks {
if hooks == nil {
return nil
}
if len(hooks.Prestart) > 0 {
return hooks
}
if len(hooks.CreateRuntime) > 0 {
return hooks
}
if len(hooks.CreateContainer) > 0 {
return hooks
}
if len(hooks.StartContainer) > 0 {
return hooks
}
if len(hooks.Poststart) > 0 {
return hooks
}
if len(hooks.Poststop) > 0 {
return hooks
}
return nil
}
// ToOCI returns the hook for an OCI runtime Spec.
func (h *Hook) ToOCI() rspec.Hook {
return rspec.Hook{
Path: h.Path,
Args: DupStringSlice(h.Args),
Env: DupStringSlice(h.Env),
Timeout: h.Timeout.Get(),
}
}
// FromOCIHooks returns hooks from an OCI runtime Spec.
func FromOCIHooks(o *rspec.Hooks) *Hooks {
if o == nil {
return nil
}
return &Hooks{
Prestart: FromOCIHookSlice(o.Prestart),
CreateRuntime: FromOCIHookSlice(o.CreateRuntime),
CreateContainer: FromOCIHookSlice(o.CreateContainer),
StartContainer: FromOCIHookSlice(o.StartContainer),
Poststart: FromOCIHookSlice(o.Poststart),
Poststop: FromOCIHookSlice(o.Poststop),
}
}
// FromOCIHookSlice returns a hook slice from an OCI runtime Spec.
func FromOCIHookSlice(o []rspec.Hook) []*Hook {
var hooks []*Hook
for _, h := range o {
hooks = append(hooks, &Hook{
Path: h.Path,
Args: DupStringSlice(h.Args),
Env: DupStringSlice(h.Env),
Timeout: Int(h.Timeout),
})
}
return hooks
}
nri-0.6.1/pkg/api/mount.go 0000664 0000000 0000000 00000004241 14610311645 0015333 0 ustar 00root root 0000000 0000000 /*
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 api
import (
"sort"
rspec "github.com/opencontainers/runtime-spec/specs-go"
)
const (
// SELinuxRelabel is a Mount pseudo-option to request relabeling.
SELinuxRelabel = "relabel"
)
// FromOCIMounts returns a Mount slice for an OCI runtime Spec.
func FromOCIMounts(o []rspec.Mount) []*Mount {
var mounts []*Mount
for _, m := range o {
mounts = append(mounts, &Mount{
Destination: m.Destination,
Type: m.Type,
Source: m.Source,
Options: DupStringSlice(m.Options),
})
}
return mounts
}
// ToOCI returns a Mount for an OCI runtime Spec.
func (m *Mount) ToOCI(propagationQuery *string) rspec.Mount {
o := rspec.Mount{
Destination: m.Destination,
Type: m.Type,
Source: m.Source,
}
for _, opt := range m.Options {
o.Options = append(o.Options, opt)
if propagationQuery != nil && (opt == "rprivate" || opt == "rshared" || opt == "rslave") {
*propagationQuery = opt
}
}
return o
}
// Cmp returns true if the mounts are equal.
func (m *Mount) Cmp(v *Mount) bool {
if v == nil {
return false
}
if m.Destination != v.Destination || m.Type != v.Type || m.Source != v.Source ||
len(m.Options) != len(v.Options) {
return false
}
mOpts := make([]string, len(m.Options))
vOpts := make([]string, len(m.Options))
sort.Strings(mOpts)
sort.Strings(vOpts)
for i, o := range mOpts {
if vOpts[i] != o {
return false
}
}
return true
}
// IsMarkedForRemoval checks if a Mount is marked for removal.
func (m *Mount) IsMarkedForRemoval() (string, bool) {
key, marked := IsMarkedForRemoval(m.Destination)
return key, marked
}
nri-0.6.1/pkg/api/namespace.go 0000664 0000000 0000000 00000001764 14610311645 0016134 0 ustar 00root root 0000000 0000000 /*
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 api
import (
rspec "github.com/opencontainers/runtime-spec/specs-go"
)
// FromOCILinuxNamespaces returns a namespace slice from an OCI runtime Spec.
func FromOCILinuxNamespaces(o []rspec.LinuxNamespace) []*LinuxNamespace {
var namespaces []*LinuxNamespace
for _, ns := range o {
namespaces = append(namespaces, &LinuxNamespace{
Type: string(ns.Type),
Path: ns.Path,
})
}
return namespaces
}
nri-0.6.1/pkg/api/optional.go 0000664 0000000 0000000 00000013745 14610311645 0016027 0 ustar 00root root 0000000 0000000 /*
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 api
import (
"os"
)
//
// XXX FIXME:
//
// The optional interface constructor should be updated/split up
// to avoid having to take an interface{} argument. Instead The
// optional types should have a
// - constructor taking the underlying native type
// - a Copy() function for copying them
// - a FromPointer constructor to create them from an optionally nil
// pointer to the underlying native type (to help constructing from
// structures that use a pointer to the native underlying type to
// denote optionality (OCI Spec mostly))
// Creating from any other type should use one of these with any explicit
// cast for the argument as necessary.
//
// String creates an Optional wrapper from its argument.
func String(v interface{}) *OptionalString {
var value string
switch o := v.(type) {
case string:
value = o
case *string:
if o == nil {
return nil
}
value = *o
case *OptionalString:
if o == nil {
return nil
}
value = o.Value
default:
return nil
}
return &OptionalString{
Value: value,
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalString) Get() *string {
if o == nil {
return nil
}
v := o.Value
return &v
}
// Int creates an Optional wrapper from its argument.
func Int(v interface{}) *OptionalInt {
var value int64
switch o := v.(type) {
case int:
value = int64(o)
case *int:
if o == nil {
return nil
}
value = int64(*o)
case *OptionalInt:
if o == nil {
return nil
}
value = o.Value
default:
return nil
}
return &OptionalInt{
Value: value,
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalInt) Get() *int {
if o == nil {
return nil
}
v := int(o.Value)
return &v
}
// Int32 creates an Optional wrapper from its argument.
func Int32(v interface{}) *OptionalInt32 {
var value int32
switch o := v.(type) {
case int32:
value = o
case *int32:
if o == nil {
return nil
}
value = *o
case *OptionalInt32:
if o == nil {
return nil
}
value = o.Value
default:
return nil
}
return &OptionalInt32{
Value: value,
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalInt32) Get() *int32 {
if o == nil {
return nil
}
v := o.Value
return &v
}
// UInt32 creates an Optional wrapper from its argument.
func UInt32(v interface{}) *OptionalUInt32 {
var value uint32
switch o := v.(type) {
case uint32:
value = o
case *uint32:
if o == nil {
return nil
}
value = *o
case *OptionalUInt32:
if o == nil {
return nil
}
value = o.Value
default:
return nil
}
return &OptionalUInt32{
Value: value,
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalUInt32) Get() *uint32 {
if o == nil {
return nil
}
v := o.Value
return &v
}
// Int64 creates an Optional wrapper from its argument.
func Int64(v interface{}) *OptionalInt64 {
var value int64
switch o := v.(type) {
case int:
value = int64(o)
case uint:
value = int64(o)
case uint64:
value = int64(o)
case int64:
value = o
case *int64:
if o == nil {
return nil
}
value = *o
case *uint64:
if o == nil {
return nil
}
value = int64(*o)
case *OptionalInt64:
if o == nil {
return nil
}
value = o.Value
default:
return nil
}
return &OptionalInt64{
Value: value,
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalInt64) Get() *int64 {
if o == nil {
return nil
}
v := o.Value
return &v
}
// UInt64 creates an Optional wrapper from its argument.
func UInt64(v interface{}) *OptionalUInt64 {
var value uint64
switch o := v.(type) {
case int:
value = uint64(o)
case uint:
value = uint64(o)
case int64:
value = uint64(o)
case uint64:
value = o
case *int64:
if o == nil {
return nil
}
value = uint64(*o)
case *uint64:
if o == nil {
return nil
}
value = *o
case *OptionalUInt64:
if o == nil {
return nil
}
value = o.Value
default:
return nil
}
return &OptionalUInt64{
Value: value,
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalUInt64) Get() *uint64 {
if o == nil {
return nil
}
v := o.Value
return &v
}
// Bool creates an Optional wrapper from its argument.
func Bool(v interface{}) *OptionalBool {
var value bool
switch o := v.(type) {
case bool:
value = o
case *bool:
if o == nil {
return nil
}
value = *o
case *OptionalBool:
if o == nil {
return nil
}
value = o.Value
default:
return nil
}
return &OptionalBool{
Value: value,
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalBool) Get() *bool {
if o == nil {
return nil
}
v := o.Value
return &v
}
// FileMode creates an Optional wrapper from its argument.
func FileMode(v interface{}) *OptionalFileMode {
var value os.FileMode
switch o := v.(type) {
case *os.FileMode:
if o == nil {
return nil
}
value = *o
case os.FileMode:
value = o
case *OptionalFileMode:
if o == nil {
return nil
}
value = os.FileMode(o.Value)
case uint32:
value = os.FileMode(o)
default:
return nil
}
return &OptionalFileMode{
Value: uint32(value),
}
}
// Get returns nil if its value is unset or a pointer to the value itself.
func (o *OptionalFileMode) Get() *os.FileMode {
if o == nil {
return nil
}
v := os.FileMode(o.Value)
return &v
}
nri-0.6.1/pkg/api/plugin.go 0000664 0000000 0000000 00000003516 14610311645 0015473 0 ustar 00root root 0000000 0000000 /*
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 api
import (
"fmt"
"strings"
)
const (
// DefaultSocketPath is the default socket path for external plugins.
DefaultSocketPath = "/var/run/nri/nri.sock"
// PluginSocketEnvVar is used to inform plugins about pre-connected sockets.
PluginSocketEnvVar = "NRI_PLUGIN_SOCKET"
// PluginNameEnvVar is used to inform NRI-launched plugins about their name.
PluginNameEnvVar = "NRI_PLUGIN_NAME"
// PluginIdxEnvVar is used to inform NRI-launched plugins about their ID.
PluginIdxEnvVar = "NRI_PLUGIN_IDX"
)
// ParsePluginName parses the (file)name of a plugin into an index and a base.
func ParsePluginName(name string) (string, string, error) {
split := strings.SplitN(name, "-", 2)
if len(split) < 2 {
return "", "", fmt.Errorf("invalid plugin name %q, idx-pluginname expected", name)
}
if err := CheckPluginIndex(split[0]); err != nil {
return "", "", err
}
return split[0], split[1], nil
}
// CheckPluginIndex checks the validity of a plugin index.
func CheckPluginIndex(idx string) error {
if len(idx) != 2 {
return fmt.Errorf("invalid plugin index %q, must be 2 digits", idx)
}
if !('0' <= idx[0] && idx[0] <= '9') || !('0' <= idx[1] && idx[1] <= '9') {
return fmt.Errorf("invalid plugin index %q (not [0-9][0-9])", idx)
}
return nil
}
nri-0.6.1/pkg/api/resources.go 0000664 0000000 0000000 00000014261 14610311645 0016206 0 ustar 00root root 0000000 0000000 /*
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 api
import (
rspec "github.com/opencontainers/runtime-spec/specs-go"
cri "k8s.io/cri-api/pkg/apis/runtime/v1"
)
// FromOCILinuxResources returns resources from an OCI runtime Spec.
func FromOCILinuxResources(o *rspec.LinuxResources, ann map[string]string) *LinuxResources {
if o == nil {
return nil
}
l := &LinuxResources{}
if m := o.Memory; m != nil {
l.Memory = &LinuxMemory{
Limit: Int64(m.Limit),
Reservation: Int64(m.Reservation),
Swap: Int64(m.Swap),
Kernel: Int64(m.Kernel),
KernelTcp: Int64(m.KernelTCP),
Swappiness: UInt64(m.Swappiness),
DisableOomKiller: Bool(m.DisableOOMKiller),
UseHierarchy: Bool(m.UseHierarchy),
}
}
if c := o.CPU; c != nil {
l.Cpu = &LinuxCPU{
Shares: UInt64(c.Shares),
Quota: Int64(c.Quota),
Period: UInt64(c.Period),
RealtimeRuntime: Int64(c.RealtimeRuntime),
RealtimePeriod: UInt64(c.RealtimePeriod),
Cpus: c.Cpus,
Mems: c.Mems,
}
}
for _, h := range o.HugepageLimits {
l.HugepageLimits = append(l.HugepageLimits, &HugepageLimit{
PageSize: h.Pagesize,
Limit: h.Limit,
})
}
for _, d := range o.Devices {
l.Devices = append(l.Devices, &LinuxDeviceCgroup{
Allow: d.Allow,
Type: d.Type,
Major: Int64(d.Major),
Minor: Int64(d.Minor),
Access: d.Access,
})
}
return l
}
func FromCRILinuxResources(c *cri.LinuxContainerResources) *LinuxResources {
if c == nil {
return nil
}
shares, quota, period := uint64(c.CpuShares), c.CpuQuota, uint64(c.CpuPeriod)
r := &LinuxResources{
Cpu: &LinuxCPU{
Shares: UInt64(&shares),
Quota: Int64("a),
Period: UInt64(&period),
Cpus: c.CpusetCpus,
Mems: c.CpusetMems,
},
Memory: &LinuxMemory{
Limit: Int64(&c.MemoryLimitInBytes),
},
}
for _, l := range c.HugepageLimits {
r.HugepageLimits = append(r.HugepageLimits,
&HugepageLimit{
PageSize: l.PageSize,
Limit: l.Limit,
})
}
return r
}
// ToOCI returns resources for an OCI runtime Spec.
func (r *LinuxResources) ToOCI() *rspec.LinuxResources {
if r == nil {
return nil
}
o := &rspec.LinuxResources{
CPU: &rspec.LinuxCPU{},
Memory: &rspec.LinuxMemory{},
}
if r.Memory != nil {
o.Memory = &rspec.LinuxMemory{
Limit: r.Memory.Limit.Get(),
Reservation: r.Memory.Reservation.Get(),
Swap: r.Memory.Swap.Get(),
Kernel: r.Memory.Kernel.Get(),
KernelTCP: r.Memory.KernelTcp.Get(),
Swappiness: r.Memory.Swappiness.Get(),
DisableOOMKiller: r.Memory.DisableOomKiller.Get(),
UseHierarchy: r.Memory.UseHierarchy.Get(),
}
}
if r.Cpu != nil {
o.CPU = &rspec.LinuxCPU{
Shares: r.Cpu.Shares.Get(),
Quota: r.Cpu.Quota.Get(),
Period: r.Cpu.Period.Get(),
RealtimeRuntime: r.Cpu.RealtimeRuntime.Get(),
RealtimePeriod: r.Cpu.RealtimePeriod.Get(),
Cpus: r.Cpu.Cpus,
Mems: r.Cpu.Mems,
}
}
for _, l := range r.HugepageLimits {
o.HugepageLimits = append(o.HugepageLimits, rspec.LinuxHugepageLimit{
Pagesize: l.PageSize,
Limit: l.Limit,
})
}
if len(r.Unified) != 0 {
o.Unified = make(map[string]string)
for k, v := range r.Unified {
o.Unified[k] = v
}
}
for _, d := range r.Devices {
o.Devices = append(o.Devices, rspec.LinuxDeviceCgroup{
Allow: d.Allow,
Type: d.Type,
Major: d.Major.Get(),
Minor: d.Minor.Get(),
Access: d.Access,
})
}
return o
}
// ToCRI returns resources for CRI.
func (r *LinuxResources) ToCRI(oomScoreAdj int64) *cri.LinuxContainerResources {
if r == nil {
return nil
}
o := &cri.LinuxContainerResources{}
if r.Memory != nil {
o.MemoryLimitInBytes = r.Memory.GetLimit().GetValue()
o.OomScoreAdj = oomScoreAdj
}
if r.Cpu != nil {
o.CpuShares = int64(r.Cpu.GetShares().GetValue())
o.CpuPeriod = int64(r.Cpu.GetPeriod().GetValue())
o.CpuQuota = r.Cpu.GetQuota().GetValue()
o.CpusetCpus = r.Cpu.Cpus
o.CpusetMems = r.Cpu.Mems
}
for _, l := range r.HugepageLimits {
o.HugepageLimits = append(o.HugepageLimits, &cri.HugepageLimit{
PageSize: l.PageSize,
Limit: l.Limit,
})
}
if len(r.Unified) != 0 {
o.Unified = make(map[string]string)
for k, v := range r.Unified {
o.Unified[k] = v
}
}
return o
}
// Copy creates a copy of the resources.
func (r *LinuxResources) Copy() *LinuxResources {
if r == nil {
return nil
}
o := &LinuxResources{}
if r.Memory != nil {
o.Memory = &LinuxMemory{
Limit: Int64(r.Memory.GetLimit()),
Reservation: Int64(r.Memory.GetReservation()),
Swap: Int64(r.Memory.GetSwap()),
Kernel: Int64(r.Memory.GetKernel()),
KernelTcp: Int64(r.Memory.GetKernelTcp()),
Swappiness: UInt64(r.Memory.GetSwappiness()),
DisableOomKiller: Bool(r.Memory.GetDisableOomKiller()),
UseHierarchy: Bool(r.Memory.GetUseHierarchy()),
}
}
if r.Cpu != nil {
o.Cpu = &LinuxCPU{
Shares: UInt64(r.Cpu.GetShares()),
Quota: Int64(r.Cpu.GetQuota()),
Period: UInt64(r.Cpu.GetPeriod()),
RealtimeRuntime: Int64(r.Cpu.GetRealtimeRuntime()),
RealtimePeriod: UInt64(r.Cpu.GetRealtimePeriod()),
Cpus: r.Cpu.GetCpus(),
Mems: r.Cpu.GetMems(),
}
}
for _, l := range r.HugepageLimits {
o.HugepageLimits = append(o.HugepageLimits, &HugepageLimit{
PageSize: l.PageSize,
Limit: l.Limit,
})
}
if len(r.Unified) != 0 {
o.Unified = make(map[string]string)
for k, v := range r.Unified {
o.Unified[k] = v
}
}
o.BlockioClass = String(r.BlockioClass)
o.RdtClass = String(r.RdtClass)
return o
}
nri-0.6.1/pkg/api/update.go 0000664 0000000 0000000 00000013707 14610311645 0015462 0 ustar 00root root 0000000 0000000 /*
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 api
//nolint
// SetContainerId sets the id of the container to update.
func (u *ContainerUpdate) SetContainerId(id string) {
u.ContainerId = id
}
// SetLinuxMemoryLimit records setting the memory limit for a container.
func (u *ContainerUpdate) SetLinuxMemoryLimit(value int64) {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.Limit = Int64(value)
}
// SetLinuxMemoryReservation records setting the memory reservation for a container.
func (u *ContainerUpdate) SetLinuxMemoryReservation(value int64) {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.Reservation = Int64(value)
}
// SetLinuxMemorySwap records records setting the memory swap limit for a container.
func (u *ContainerUpdate) SetLinuxMemorySwap(value int64) {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.Swap = Int64(value)
}
// SetLinuxMemoryKernel records setting the memory kernel limit for a container.
func (u *ContainerUpdate) SetLinuxMemoryKernel(value int64) {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.Kernel = Int64(value)
}
// SetLinuxMemoryKernelTCP records setting the memory kernel TCP limit for a container.
func (u *ContainerUpdate) SetLinuxMemoryKernelTCP(value int64) {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.KernelTcp = Int64(value)
}
// SetLinuxMemorySwappiness records setting the memory swappiness for a container.
func (u *ContainerUpdate) SetLinuxMemorySwappiness(value uint64) {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.Swappiness = UInt64(value)
}
// SetLinuxMemoryDisableOomKiller records disabling the OOM killer for a container.
func (u *ContainerUpdate) SetLinuxMemoryDisableOomKiller() {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.DisableOomKiller = Bool(true)
}
// SetLinuxMemoryUseHierarchy records enabling hierarchical memory accounting for a container.
func (u *ContainerUpdate) SetLinuxMemoryUseHierarchy() {
u.initLinuxResourcesMemory()
u.Linux.Resources.Memory.UseHierarchy = Bool(true)
}
// SetLinuxCPUShares records setting the scheduler's CPU shares for a container.
func (u *ContainerUpdate) SetLinuxCPUShares(value uint64) {
u.initLinuxResourcesCPU()
u.Linux.Resources.Cpu.Shares = UInt64(value)
}
// SetLinuxCPUQuota records setting the scheduler's CPU quota for a container.
func (u *ContainerUpdate) SetLinuxCPUQuota(value int64) {
u.initLinuxResourcesCPU()
u.Linux.Resources.Cpu.Quota = Int64(value)
}
// SetLinuxCPUPeriod records setting the scheduler's CPU period for a container.
func (u *ContainerUpdate) SetLinuxCPUPeriod(value int64) {
u.initLinuxResourcesCPU()
u.Linux.Resources.Cpu.Period = UInt64(value)
}
// SetLinuxCPURealtimeRuntime records setting the scheduler's realtime runtime for a container.
func (u *ContainerUpdate) SetLinuxCPURealtimeRuntime(value int64) {
u.initLinuxResourcesCPU()
u.Linux.Resources.Cpu.RealtimeRuntime = Int64(value)
}
// SetLinuxCPURealtimePeriod records setting the scheduler's realtime period for a container.
func (u *ContainerUpdate) SetLinuxCPURealtimePeriod(value uint64) {
u.initLinuxResourcesCPU()
u.Linux.Resources.Cpu.RealtimePeriod = UInt64(value)
}
// SetLinuxCPUSetCPUs records setting the cpuset CPUs for a container.
func (u *ContainerUpdate) SetLinuxCPUSetCPUs(value string) {
u.initLinuxResourcesCPU()
u.Linux.Resources.Cpu.Cpus = value
}
// SetLinuxCPUSetMems records setting the cpuset memory for a container.
func (u *ContainerUpdate) SetLinuxCPUSetMems(value string) {
u.initLinuxResourcesCPU()
u.Linux.Resources.Cpu.Mems = value
}
// AddLinuxHugepageLimit records adding a hugepage limit for a container.
func (u *ContainerUpdate) AddLinuxHugepageLimit(pageSize string, value uint64) {
u.initLinuxResources()
u.Linux.Resources.HugepageLimits = append(u.Linux.Resources.HugepageLimits,
&HugepageLimit{
PageSize: pageSize,
Limit: value,
})
}
// SetLinuxBlockIOClass records setting the Block I/O class for a container.
func (u *ContainerUpdate) SetLinuxBlockIOClass(value string) {
u.initLinuxResources()
u.Linux.Resources.BlockioClass = String(value)
}
// SetLinuxRDTClass records setting the RDT class for a container.
func (u *ContainerUpdate) SetLinuxRDTClass(value string) {
u.initLinuxResources()
u.Linux.Resources.RdtClass = String(value)
}
// AddLinuxUnified sets a cgroupv2 unified resource.
func (u *ContainerUpdate) AddLinuxUnified(key, value string) {
u.initLinuxResourcesUnified()
u.Linux.Resources.Unified[key] = value
}
// SetIgnoreFailure marks an Update as ignored for failures.
// Such updates will not prevent the related container operation
// from succeeding if the update fails.
func (u *ContainerUpdate) SetIgnoreFailure() {
u.IgnoreFailure = true
}
//
// Initializing a container update.
//
func (u *ContainerUpdate) initLinux() {
if u.Linux == nil {
u.Linux = &LinuxContainerUpdate{}
}
}
func (u *ContainerUpdate) initLinuxResources() {
u.initLinux()
if u.Linux.Resources == nil {
u.Linux.Resources = &LinuxResources{}
}
}
func (u *ContainerUpdate) initLinuxResourcesMemory() {
u.initLinuxResources()
if u.Linux.Resources.Memory == nil {
u.Linux.Resources.Memory = &LinuxMemory{}
}
}
func (u *ContainerUpdate) initLinuxResourcesCPU() {
u.initLinuxResources()
if u.Linux.Resources.Cpu == nil {
u.Linux.Resources.Cpu = &LinuxCPU{}
}
}
func (u *ContainerUpdate) initLinuxResourcesUnified() {
u.initLinuxResources()
if u.Linux.Resources.Unified == nil {
u.Linux.Resources.Unified = make(map[string]string)
}
}
nri-0.6.1/pkg/log/ 0000775 0000000 0000000 00000000000 14610311645 0013651 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/log/log.go 0000664 0000000 0000000 00000004761 14610311645 0014771 0 ustar 00root root 0000000 0000000 /*
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
import (
"context"
"github.com/sirupsen/logrus"
)
var (
log Logger = &fallbackLogger{}
)
// Logger is the interface NRI uses for logging.
type Logger interface {
Debugf(ctx context.Context, format string, args ...interface{})
Infof(ctx context.Context, format string, args ...interface{})
Warnf(ctx context.Context, format string, args ...interface{})
Errorf(ctx context.Context, format string, args ...interface{})
}
// Set the logger used by NRI.
func Set(l Logger) {
log = l
}
// Get the logger used by NRI.
func Get() Logger {
return log
}
// Debugf logs a formatted debug message.
func Debugf(ctx context.Context, format string, args ...interface{}) {
log.Debugf(ctx, format, args...)
}
// Infof logs a formatted informational message.
func Infof(ctx context.Context, format string, args ...interface{}) {
log.Infof(ctx, format, args...)
}
// Warnf logs a formatted warning message.
func Warnf(ctx context.Context, format string, args ...interface{}) {
log.Warnf(ctx, format, args...)
}
// Errorf logs a formatted error message.
func Errorf(ctx context.Context, format string, args ...interface{}) {
log.Errorf(ctx, format, args...)
}
type fallbackLogger struct{}
// Debugf logs a formatted debug message.
func (f *fallbackLogger) Debugf(ctx context.Context, format string, args ...interface{}) {
logrus.WithContext(ctx).Debugf(format, args...)
}
// Infof logs a formatted informational message.
func (f *fallbackLogger) Infof(ctx context.Context, format string, args ...interface{}) {
logrus.WithContext(ctx).Infof(format, args...)
}
// Warnf logs a formatted warning message.
func (f *fallbackLogger) Warnf(ctx context.Context, format string, args ...interface{}) {
logrus.WithContext(ctx).Warnf(format, args...)
}
// Errorf logs a formatted error message.
func (f *fallbackLogger) Errorf(ctx context.Context, format string, args ...interface{}) {
logrus.WithContext(ctx).Errorf(format, args...)
}
nri-0.6.1/pkg/net/ 0000775 0000000 0000000 00000000000 14610311645 0013656 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/net/conn.go 0000664 0000000 0000000 00000004373 14610311645 0015151 0 ustar 00root root 0000000 0000000 /*
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 net
import (
"fmt"
"io"
"net"
"os"
"strconv"
"sync"
)
// NewFdConn creates a net.Conn for the given (socket) fd.
func NewFdConn(fd int) (net.Conn, error) {
f := os.NewFile(uintptr(fd), "fd #"+strconv.Itoa(fd))
conn, err := net.FileConn(f)
if err != nil {
return nil, fmt.Errorf("failed to create net.Conn for fd #%d: %w", fd, err)
}
f.Close()
return conn, nil
}
// connListener wraps a pre-connected socket in a net.Listener.
type connListener struct {
next chan net.Conn
conn net.Conn
addr net.Addr
lock sync.RWMutex // for Close()
closed bool
}
// NewConnListener wraps an existing net.Conn in a net.Listener.
//
// The first call to Accept() on the listener will return the wrapped
// connection. Subsequent calls to Accept() block until the listener
// is closed, then return io.EOF. Close() closes the listener and the
// wrapped connection.
func NewConnListener(conn net.Conn) net.Listener {
next := make(chan net.Conn, 1)
next <- conn
return &connListener{
next: next,
conn: conn,
addr: conn.LocalAddr(),
}
}
// Accept returns the wrapped connection when it is called the first
// time. Later calls to Accept block until the listener is closed, then
// return io.EOF.
func (l *connListener) Accept() (net.Conn, error) {
conn := <-l.next
if conn == nil {
return nil, io.EOF
}
return conn, nil
}
// Close closes the listener and the wrapped connection.
func (l *connListener) Close() error {
l.lock.Lock()
defer l.lock.Unlock()
if l.closed {
return nil
}
close(l.next)
l.closed = true
return l.conn.Close()
}
// Addr returns the local address of the wrapped connection.
func (l *connListener) Addr() net.Addr {
return l.addr
}
nri-0.6.1/pkg/net/conn_test.go 0000664 0000000 0000000 00000004162 14610311645 0016204 0 ustar 00root root 0000000 0000000 /*
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 net_test
import (
"bufio"
"errors"
"fmt"
"io"
"github.com/containerd/nri/pkg/net"
"testing"
require "github.com/stretchr/testify/require"
)
func TestPreconnectedReadWrite(t *testing.T) {
sp, err := net.NewSocketPair()
require.NoError(t, err, "NewSocketPair()")
require.NotNil(t, sp, "NewSocketPair()")
conn, err := sp.LocalConn()
require.NoError(t, err, "LocalConn()")
require.NotNil(t, conn, "LocalConn()")
sent := []string{}
recv := []string{}
done := make(chan error, 1)
reader := func() {
conn, err := sp.PeerConn()
require.NoError(t, err, "PeerConn()")
require.NotNil(t, conn, "PeerConn()")
l := net.NewConnListener(conn)
require.NotNil(t, l, "NewConnListener()")
pconn, err := l.Accept()
require.NoError(t, err, "Accept()")
require.NotNil(t, pconn, "Accept()")
buf := bufio.NewReader(pconn)
for {
msg, err := buf.ReadString('\n')
if err != nil {
if !errors.Is(err, io.EOF) {
done <- fmt.Errorf("ReadString() failed: %w", err)
}
break
}
recv = append(recv, msg)
}
close(done)
}
go reader()
l := net.NewConnListener(conn)
require.NotNil(t, l, "NewConnListener()")
lconn, err := l.Accept()
require.NoError(t, err, "Accept()")
require.NotNil(t, lconn, "Accept()")
for i := 0; i < 32; i++ {
msg := fmt.Sprintf("message #%d\n", i)
_, err := lconn.Write([]byte(msg))
require.NoError(t, err, "Write()")
sent = append(sent, msg)
}
lconn.Close()
err = <-done
require.NoError(t, err, "done/reader")
require.Equal(t, sent, recv, "send and received data")
}
nri-0.6.1/pkg/net/multiplex/ 0000775 0000000 0000000 00000000000 14610311645 0015701 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/net/multiplex/mux.go 0000664 0000000 0000000 00000023405 14610311645 0017045 0 ustar 00root root 0000000 0000000 /*
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 multiplex
import (
"encoding/binary"
"errors"
"fmt"
"io"
"net"
"sync"
"syscall"
"time"
nrinet "github.com/containerd/nri/pkg/net"
"github.com/containerd/ttrpc"
)
// Mux multiplexes several logical connections over a single net.Conn.
//
// Connections are identified within a Mux by ConnIDs which are simple
// 32-bit unsigned integers. Opening a connection returns a net.Conn
// corrponding to the ConnID. This can then be used to write and read
// data through the connection with the Mux performing multiplexing
// and demultiplexing of data.
//
// Writing to a connection is fully synchronous. The caller can safely
// reuse the buffer once the call returns. Reading from a connection
// returns the oldest demultiplexed buffer for the connection, blocking
// if the connections incoming queue is empty. If any incoming queue is
// ever overflown the underlying trunk and all multiplexed connections
// are closed and an error is recorded. This error is later returned by
// any subsequent read from any connection. All connections of the Mux
// have the same fixed incoming queue length which can be configured
// using the WithReadQueueLength Option during Mux creation.
//
// The Mux interface also provides functions that emulate net.Dial and
// net.Listen for a connection. Usually these can be used for passing
// multiplexed connections to packages that insist to Dial or Accept
// themselves for connection establishment.
//
// Note that opening a connection is a virtual operation in the sense
// that it has no effects outside the Mux. It is performed without any
// signalling or other communication. It merely acquires the net.Conn
// corresponding to the connection and blindly assumes that the same
// ConnID is or will be opened at the other end of the Mux.
type Mux interface {
// Open the connection for the given ConnID.
Open(ConnID) (net.Conn, error)
// Close the Mux and all connections associated with it.
Close() error
// Dialer returns a net.Dial-like function for the connection.
//
// Calling the returned function (with arguments) will return a
// net.Conn for the connection.
Dialer(ConnID) func(string, string) (net.Conn, error)
// Listener returns a net.Listener for the connection. The first
// call to Accept() on the listener will return a net.Conn for the
// connection. Subsequent calls to Accept() will block until the
// connection is closed then return io.EOF.
Listen(ConnID) (net.Listener, error)
// Trunk returns the trunk connection for the Mux.
Trunk() net.Conn
// Unblock unblocks the Mux reader.
Unblock()
}
// ConnID uniquely identifies a logical connection within a Mux.
type ConnID uint32
const (
// ConnID 0 is reserved for future use.
reservedConnID ConnID = iota
// LowestConnID is the lowest externally usable ConnID.
LowestConnID
)
// Option to apply to a Mux.
type Option func(*mux)
// WithBlockedRead causes the Mux to be blocked for reading until gets Unblock()'ed.
func WithBlockedRead() Option {
return func(m *mux) {
if m.blockC == nil {
m.blockC = make(chan struct{})
}
}
}
// WithReadQueueLength overrides the default read queue size.
func WithReadQueueLength(length int) Option {
return func(m *mux) {
m.qlen = length
}
}
// Multiplex returns a multiplexer for the given connection.
func Multiplex(trunk net.Conn, options ...Option) Mux {
return newMux(trunk, options...)
}
// mux is our implementation of Mux.
type mux struct {
trunk net.Conn
writeLock sync.Mutex
conns map[ConnID]*conn
connLock sync.RWMutex
qlen int
errOnce sync.Once
err error
unblkOnce sync.Once
blockC chan struct{}
closeOnce sync.Once
doneC chan struct{}
}
const (
// default read queue length for a single connection
readQueueLen = 256
// length of frame header: 4-byte ConnID, 4-byte payload length
headerLen = 8
// max. allowed payload size
maxPayloadSize = 1 << 24
)
// conn represents a single multiplexed connection.
type conn struct {
id ConnID
mux *mux
readC chan []byte
closeOnce sync.Once
doneC chan error
}
func newMux(trunk net.Conn, options ...Option) *mux {
m := &mux{
trunk: trunk,
conns: make(map[ConnID]*conn),
qlen: readQueueLen,
doneC: make(chan struct{}),
}
for _, o := range options {
o(m)
}
if m.blockC == nil {
WithBlockedRead()(m)
m.Unblock()
}
go m.reader()
return m
}
func (m *mux) Trunk() net.Conn {
return m.trunk
}
func (m *mux) Unblock() {
m.unblkOnce.Do(func() {
close(m.blockC)
})
}
func (m *mux) Open(id ConnID) (net.Conn, error) {
if id == reservedConnID {
return nil, fmt.Errorf("ConnID %d is reserved", id)
}
m.connLock.Lock()
defer m.connLock.Unlock()
c, ok := m.conns[id]
if !ok {
c = &conn{
id: id,
mux: m,
doneC: make(chan error, 1),
readC: make(chan []byte, m.qlen),
}
m.conns[id] = c
}
return c, nil
}
func (m *mux) Close() error {
m.closeOnce.Do(func() {
m.connLock.Lock()
defer m.connLock.Unlock()
for _, conn := range m.conns {
conn.close()
}
close(m.doneC)
m.trunk.Close()
})
return nil
}
func (m *mux) Dialer(id ConnID) func(string, string) (net.Conn, error) {
return func(string, string) (net.Conn, error) {
return m.Open(id)
}
}
func (m *mux) Listen(id ConnID) (net.Listener, error) {
conn, err := m.Open(id)
if err != nil {
return nil, err
}
return nrinet.NewConnListener(conn), nil
}
func (m *mux) write(id ConnID, buf []byte) (int, error) {
var hdr [headerLen]byte
if len(buf) > maxPayloadSize {
return 0, syscall.EMSGSIZE
}
binary.BigEndian.PutUint32(hdr[0:4], uint32(id))
binary.BigEndian.PutUint32(hdr[4:8], uint32(len(buf)))
m.writeLock.Lock()
defer m.writeLock.Unlock()
n, err := m.trunk.Write(hdr[:])
if err != nil {
err = fmt.Errorf("failed to write header to trunk: %w", err)
if n != 0 {
m.setError(err)
m.Close()
}
return 0, err
}
n, err = m.trunk.Write(buf)
if err != nil {
err = fmt.Errorf("failed to write payload to trunk: %w", err)
if n != 0 {
m.setError(err)
m.Close()
}
}
return n, err
}
func (m *mux) reader() {
var (
hdr [headerLen]byte
cid uint32
cnt uint32
buf []byte
err error
)
<-m.blockC
for {
select {
case <-m.doneC:
return
default:
}
_, err = io.ReadFull(m.trunk, hdr[:])
if err != nil {
switch {
case errors.Is(err, io.EOF):
case errors.Is(err, ttrpc.ErrClosed):
err = io.EOF
case errors.Is(err, ttrpc.ErrServerClosed):
err = io.EOF
case errors.Is(err, net.ErrClosed):
err = io.EOF
default:
err = fmt.Errorf("failed to read header from trunk: %w", err)
}
m.setError(err)
m.Close()
return
}
cid = binary.BigEndian.Uint32(hdr[0:4])
cnt = binary.BigEndian.Uint32(hdr[4:8])
buf = make([]byte, int(cnt))
_, err = io.ReadFull(m.trunk, buf)
if err != nil {
switch {
case errors.Is(err, io.EOF):
case errors.Is(err, ttrpc.ErrClosed):
err = io.EOF
case errors.Is(err, ttrpc.ErrServerClosed):
err = io.EOF
case errors.Is(err, net.ErrClosed):
err = io.EOF
default:
err = fmt.Errorf("failed to read payload from trunk: %w", err)
}
m.setError(err)
m.Close()
return
}
m.connLock.RLock()
conn, ok := m.conns[ConnID(cid)]
m.connLock.RUnlock()
if ok {
select {
case conn.readC <- buf:
default:
m.setError(errors.New("failed to queue payload for reading"))
m.Close()
return
}
}
}
}
func (m *mux) setError(err error) {
m.errOnce.Do(func() {
m.err = err
})
}
// nolint
func (m *mux) error() error {
m.errOnce.Do(func() {
if m.err == nil {
m.err = io.EOF
}
})
return m.err
}
//
// multiplexed connections
//
// Reads reads the next message from the multiplexed connection.
func (c *conn) Read(buf []byte) (int, error) {
var (
msg []byte
err error
ok bool
)
select {
case err, ok = <-c.doneC:
if !ok || err == nil {
err = c.mux.error()
}
return 0, err
case msg, ok = <-c.readC:
if !ok {
return 0, c.mux.error()
}
if cap(buf) < len(msg) {
return 0, syscall.ENOMEM
}
}
copy(buf, msg)
return len(msg), nil
}
// Write writes the given data to the multiplexed connection.
func (c *conn) Write(b []byte) (int, error) {
select {
case err := <-c.doneC:
if err == nil {
err = io.EOF
}
return 0, err
default:
}
return c.mux.write(c.id, b)
}
// Close closes the multiplexed connection.
func (c *conn) Close() error {
c.mux.connLock.Lock()
defer c.mux.connLock.Unlock()
if c.mux.conns[c.id] == c {
delete(c.mux.conns, c.id)
}
return c.close()
}
func (c *conn) close() error {
c.closeOnce.Do(func() {
close(c.doneC)
})
return nil
}
// LocalAddr is the unimplemented stub for the corresponding net.Conn function.
func (c *conn) LocalAddr() net.Addr {
return nil
}
// RemoteAddr is the unimplemented stub for the corresponding net.Conn function.
func (c *conn) RemoteAddr() net.Addr {
return nil
}
// SetDeadline is the unimplemented stub for the corresponding net.Conn function.
func (c *conn) SetDeadline(t time.Time) error {
return nil
}
// SetReadDeadline is the unimplemented stub for the corresponding net.Conn function.
func (c *conn) SetReadDeadline(t time.Time) error {
return nil
}
// SetWriteDeadline is the unimplemented stub for the corresponding net.Conn function.
func (c *conn) SetWriteDeadline(t time.Time) error {
return nil
}
nri-0.6.1/pkg/net/multiplex/mux_suite_test.go 0000664 0000000 0000000 00000026514 14610311645 0021321 0 ustar 00root root 0000000 0000000 /*
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 multiplex_test
import (
"fmt"
"net"
"sync"
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
nrinet "github.com/containerd/nri/pkg/net"
mux "github.com/containerd/nri/pkg/net/multiplex"
)
func TestMultiplex(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Connection Multiplexer")
}
var _ = Describe("Emulated Connection Setup, Open", func() {
var (
lMux, pMux mux.Mux
connID mux.ConnID
lConn, pConn net.Conn
err error
)
BeforeEach(func() {
lMux, pMux, err = connectMuxes()
Expect(err).To(BeNil())
Expect(lMux).ToNot(BeNil())
Expect(pMux).ToNot(BeNil())
connID = mux.LowestConnID
})
AfterEach(func() {
if lMux != nil {
lMux.Close()
}
if pMux != nil {
pMux.Close()
}
})
It("Open should return a net.Conn", func() {
// When
lConn, err = lMux.Open(connID)
// Then
Expect(err).To(BeNil())
Expect(lConn).ToNot(BeNil())
})
It("Opened net.Conn should allow sending", func() {
// Given
lConn, err = lMux.Open(connID)
Expect(err).To(BeNil())
Expect(lConn).ToNot(BeNil())
// When
_, err = lConn.Write([]byte("this is a test message"))
// Then
Expect(err).To(BeNil())
})
It("Opened net.Conn should allow receiving", func() {
// Given
pConn, err = pMux.Open(connID)
Expect(err).To(BeNil())
Expect(pConn).ToNot(BeNil())
// When
lConn, err = lMux.Open(connID)
Expect(err).To(BeNil())
Expect(lConn).ToNot(BeNil())
msg := "this is a test message"
_, err = lConn.Write([]byte(msg))
Expect(err).To(BeNil())
// Then
buf := make([]byte, len(msg))
_, err = pConn.Read(buf)
Expect(err).To(BeNil())
Expect(string(buf)).To(Equal(msg))
})
})
var _ = Describe("Emulated Connection Setup, Close", func() {
var (
lMux, pMux mux.Mux
connID mux.ConnID
lConn, pConn net.Conn
err error
)
BeforeEach(func() {
lMux, pMux, err = connectMuxes()
Expect(err).To(BeNil())
Expect(lMux).ToNot(BeNil())
Expect(pMux).ToNot(BeNil())
connID = mux.LowestConnID
lConn, err = lMux.Open(connID)
Expect(err).To(BeNil())
Expect(lConn).ToNot(BeNil())
pConn, err = pMux.Open(connID)
Expect(err).To(BeNil())
Expect(pConn).ToNot(BeNil())
})
AfterEach(func() {
if lMux != nil {
lMux.Close()
}
if pMux != nil {
pMux.Close()
}
})
It("Closed connection should fail sending", func() {
// Given
msg := "this is a test message"
_, err = lConn.Write([]byte(msg))
Expect(err).To(BeNil())
// When
err = lConn.Close()
Expect(err).To(BeNil())
// Then
_, err = lConn.Write([]byte(msg))
Expect(err).ToNot(BeNil())
})
It("Closed connection should fail receiving", func() {
// Given
err = pConn.Close()
Expect(err).To(BeNil())
// When
buf := make([]byte, 64)
_, err = pConn.Read(buf)
// Then
Expect(err).ToNot(BeNil())
})
})
var _ = Describe("Emulated Connection Setup, Dial", func() {
var (
lMux, pMux mux.Mux
connID mux.ConnID
conn net.Conn
err error
)
BeforeEach(func() {
lMux, pMux, err = connectMuxes()
Expect(err).To(BeNil())
Expect(lMux).ToNot(BeNil())
Expect(pMux).ToNot(BeNil())
connID = mux.LowestConnID
})
AfterEach(func() {
if lMux != nil {
lMux.Close()
}
if pMux != nil {
pMux.Close()
}
})
dial := func(m mux.Mux, connID mux.ConnID) (net.Conn, error) {
return m.Dialer(connID)("mux", "id")
}
It("Dial should return a net.Conn", func() {
// When
conn, err = dial(lMux, connID)
// Then
Expect(err).To(BeNil())
Expect(conn).ToNot(BeNil())
})
It("Dialed net.Conn should allow sending", func() {
// Given
conn, err = dial(lMux, connID)
Expect(err).To(BeNil())
Expect(conn).ToNot(BeNil())
// When
_, err = conn.Write([]byte("this is a test message"))
// Then
Expect(err).To(BeNil())
})
})
var _ = Describe("Emulated Connection Setup, Listen, Accept", func() {
var (
lMux, pMux mux.Mux
connID mux.ConnID
l net.Listener
lConn, pConn net.Conn
err error
)
BeforeEach(func() {
lMux, pMux, err = connectMuxes()
Expect(err).To(BeNil())
Expect(lMux).ToNot(BeNil())
Expect(pMux).ToNot(BeNil())
connID = mux.LowestConnID
})
AfterEach(func() {
if lMux != nil {
lMux.Close()
}
if pMux != nil {
pMux.Close()
}
})
accept := func(m mux.Mux, connID mux.ConnID) (net.Conn, error) {
l, err = m.Listen(connID)
if err != nil {
return nil, err
}
return l.Accept()
}
It("Listen should return a net.Listener", func() {
// When
l, err = pMux.Listen(connID)
// Then
Expect(err).To(BeNil())
Expect(l).ToNot(BeNil())
})
It("Accept on the net.Listener should return a net.Conn", func() {
// When
pConn, err = accept(pMux, connID)
// Then
Expect(err).To(BeNil())
Expect(pConn).ToNot(BeNil())
})
It("Accepted net.Conn should allow receiving", func() {
// Given
pConn, err = accept(pMux, connID)
Expect(err).To(BeNil())
Expect(pConn).ToNot(BeNil())
// When
lConn, err = lMux.Open(connID)
Expect(err).To(BeNil())
Expect(lConn).ToNot(BeNil())
msg := "this is a test message"
_, err = lConn.Write([]byte(msg))
Expect(err).To(BeNil())
// Then
buf := make([]byte, len(msg))
_, err = pConn.Read(buf)
Expect(err).To(BeNil())
Expect(string(buf)).To(Equal(msg))
})
})
var _ = Describe("Transmitting data", func() {
var (
lMux mux.Mux
pMux mux.Mux
err error
)
When("single connection", func() {
It("send and receive messages", func() {
connCnt := 1
msgCnt := 64
lMux, pMux, err = connectMuxes()
Expect(err).To(BeNil())
Expect(lMux).ToNot(BeNil())
Expect(pMux).ToNot(BeNil())
lConn, pConn, err := openMuxes(lMux, pMux, connCnt)
Expect(err).To(BeNil())
Expect(len(lConn)).To(Equal(connCnt))
Expect(len(pConn)).To(Equal(connCnt))
sendAndReceive(lConn, pConn, msgCnt)
})
})
When("multiple connections", func() {
It("send and receive messages concurrently", func() {
connCnt := 16
msgCnt := 64
lMux, pMux, err = connectMuxes()
Expect(err).To(BeNil())
Expect(lMux).ToNot(BeNil())
Expect(pMux).ToNot(BeNil())
lConn, pConn, err := openMuxes(lMux, pMux, connCnt)
Expect(err).To(BeNil())
Expect(len(lConn)).To(Equal(connCnt))
Expect(len(pConn)).To(Equal(connCnt))
sendAndReceive(lConn, pConn, msgCnt)
})
})
})
/*
// TODO
var _ = Describe("Read Queue Length", func() {
var (
lMux, pMux mux.Mux
connID mux.ConnID
lConn, pConn net.Conn
err error
qLen = 1
)
BeforeEach(func() {
lMux, pMux, err = connectMuxes(mux.WithReadQueueLength(qLen))
Expect(err).To(BeNil())
Expect(lMux).ToNot(BeNil())
Expect(pMux).ToNot(BeNil())
connID = mux.LowestConnID
lConn, err = lMux.Open(connID)
Expect(err).To(BeNil())
Expect(lConn).ToNot(BeNil())
pConn, err = pMux.Open(connID)
Expect(err).To(BeNil())
Expect(pConn).ToNot(BeNil())
})
AfterEach(func() {
if lMux != nil {
lMux.Close()
}
if pMux != nil {
pMux.Close()
}
})
It("Messages get queued up till queue length", func() {
var msg string
// When
for i := 0; i < qLen; i++ {
msg = fmt.Sprintf("qlen test message #%d", i)
_, err = lConn.Write([]byte(msg))
Expect(err).To(BeNil())
}
// Then
buf := make([]byte, len(msg))
for i := 0; i < qLen; i++ {
_, err = pConn.Read(buf)
Expect(err).To(BeNil())
}
})
It("Queue overflow closes mux, connections, results in read error", func() {
var msg string
// When
for i := 0; i < qLen+1; i++ {
msg = fmt.Sprintf("qlen test message #%d", i)
_, err = lConn.Write([]byte(msg))
Expect(err).To(BeNil())
}
// Then
buf := make([]byte, len(msg))
for i := 0; i < qLen; i++ {
_, err = pConn.Read(buf)
}
_, err = pConn.Read(buf)
Expect(err).ToNot(BeNil())
})
})
var _ = Describe("Blocking and Unblocking", func() {
// TODO...
})
*/
// getSocketPairConn returns connections for a socketpair.
func getSocketPairConn() (net.Conn, net.Conn, error) {
fds, err := nrinet.NewSocketPair()
if err != nil {
return nil, nil, err
}
lConn, err := fds.LocalConn()
if err != nil {
fds.LocalClose()
fds.PeerClose()
return nil, nil, err
}
pConn, err := fds.PeerConn()
if err != nil {
fds.LocalClose()
fds.PeerClose()
return nil, nil, err
}
return lConn, pConn, nil
}
// connectMuxes returns a pair of connected muxes.
func connectMuxes(options ...mux.Option) (mux.Mux, mux.Mux, error) {
lConn, pConn, err := getSocketPairConn()
if err != nil {
return nil, nil, err
}
return mux.Multiplex(lConn, options...), mux.Multiplex(pConn, options...), nil
}
// openMuxes opens a number of connections for a pair of connected muxes.
func openMuxes(lMux, pMux mux.Mux, count int) ([]net.Conn, []net.Conn, error) {
var (
lConn []net.Conn
pConn []net.Conn
conn net.Conn
err error
)
for i := 0; i < count; i++ {
conn, err = lMux.Open(mux.LowestConnID + mux.ConnID(i))
if err != nil {
lMux.Trunk().Close()
pMux.Trunk().Close()
return nil, nil, err
}
lConn = append(lConn, conn)
conn, err = pMux.Open(mux.LowestConnID + mux.ConnID(i))
if err != nil {
lMux.Trunk().Close()
pMux.Trunk().Close()
return nil, nil, err
}
pConn = append(pConn, conn)
}
return lConn, pConn, nil
}
func sendAndReceive(lConn, pConn []net.Conn, msgCount int) {
var (
wg = &sync.WaitGroup{}
start = make(chan struct{})
maxMsg = 64
endMsg = ""
)
// message sender
write := func(id int, conn net.Conn, messages []string) []string {
var (
msg string
cnt int
err error
)
if messages == nil {
for i := 0; i < msgCount; i++ {
msg := fmt.Sprintf("[%d] message #%d/%d", id, i+1, msgCount)
Expect(len(msg) <= maxMsg).To(BeTrue())
messages = append(messages, msg)
}
}
for _, msg = range messages {
cnt, err = conn.Write([]byte(msg))
Expect(err).To(BeNil())
Expect(cnt).To(Equal(len(msg)))
}
cnt, err = conn.Write([]byte(endMsg))
Expect(err).To(BeNil())
Expect(cnt).To(Equal(len(endMsg)))
return messages
}
// mesage receiver and collector
read := func(conn net.Conn) []string {
var (
msg = make([]byte, maxMsg)
recv []string
cnt int
err error
)
for {
cnt, err = conn.Read(msg)
Expect(err).To(BeNil())
if cnt == 0 {
return recv
}
recv = append(recv, string(msg[:cnt]))
}
}
// send and receive, or the other way around, check echoed messages for equality
sendrecv := func(id int, conn net.Conn, sender bool) {
var (
sent []string
recv []string
)
defer wg.Done()
<-start
if sender {
sent = write(id, conn, nil)
recv = read(conn)
Expect(sent).To(Equal(recv))
} else {
recv = read(conn)
write(id, conn, recv)
}
}
// set up senders and receivers, waiting for a trigger to start
for i := 0; i < len(lConn); i++ {
go sendrecv(i, lConn[i], true)
go sendrecv(i, pConn[i], false)
wg.Add(2)
}
// trigger senders/recevers and wait for them to finish
close(start)
wg.Wait()
}
nri-0.6.1/pkg/net/multiplex/ttrpc.go 0000664 0000000 0000000 00000001474 14610311645 0017372 0 ustar 00root root 0000000 0000000 /*
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 multiplex
const (
// PluginServiceConn is the mux connection ID for NRI plugin services.
PluginServiceConn ConnID = iota + 1
// RuntimeServiceConn is the mux connection ID for NRI runtime services.
RuntimeServiceConn
)
nri-0.6.1/pkg/net/net_suite_test.go 0000664 0000000 0000000 00000001460 14610311645 0017244 0 ustar 00root root 0000000 0000000 /*
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 net_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
func TestNet(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Net pre-connected Connections and SocketPair")
}
nri-0.6.1/pkg/net/socketpair.go 0000664 0000000 0000000 00000004646 14610311645 0016363 0 ustar 00root root 0000000 0000000 /*
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 net
import (
"fmt"
"net"
"os"
)
// SocketPair contains the os.File of a connected pair of sockets.
type SocketPair struct {
local, peer *os.File
}
// NewSocketPair returns a connected pair of sockets.
func NewSocketPair() (SocketPair, error) {
fds, err := newSocketPairCLOEXEC()
if err != nil {
return SocketPair{nil, nil}, fmt.Errorf("failed to create socketpair: %w", err)
}
filename := fmt.Sprintf("socketpair-#%d:%d", fds[0], fds[1])
return SocketPair{
os.NewFile(uintptr(fds[0]), filename+"[0]"),
os.NewFile(uintptr(fds[1]), filename+"[1]"),
}, nil
}
// LocalFile returns the local end of the socketpair as an *os.File.
func (sp SocketPair) LocalFile() *os.File {
return sp.local
}
// PeerFile returns the peer end of the socketpair as an *os.File.
func (sp SocketPair) PeerFile() *os.File {
return sp.peer
}
// LocalConn returns a net.Conn for the local end of the socketpair.
// This closes LocalFile().
func (sp SocketPair) LocalConn() (net.Conn, error) {
file := sp.LocalFile()
defer file.Close()
conn, err := net.FileConn(file)
if err != nil {
return nil, fmt.Errorf("failed to create net.Conn for %s: %w", file.Name(), err)
}
return conn, nil
}
// PeerConn returns a net.Conn for the peer end of the socketpair.
// This closes PeerFile().
func (sp SocketPair) PeerConn() (net.Conn, error) {
file := sp.PeerFile()
defer file.Close()
conn, err := net.FileConn(file)
if err != nil {
return nil, fmt.Errorf("failed to create net.Conn for %s: %w", file.Name(), err)
}
return conn, nil
}
// Close closes both ends of the socketpair.
func (sp SocketPair) Close() {
sp.LocalClose()
sp.PeerClose()
}
// LocalClose closes the local end of the socketpair.
func (sp SocketPair) LocalClose() {
sp.local.Close()
}
// PeerClose closes the peer end of the socketpair.
func (sp SocketPair) PeerClose() {
sp.peer.Close()
}
nri-0.6.1/pkg/net/socketpair_cloexec_linux.go 0000664 0000000 0000000 00000001425 14610311645 0021274 0 ustar 00root root 0000000 0000000 //go:build linux
/*
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 net
import (
"golang.org/x/sys/unix"
)
func newSocketPairCLOEXEC() ([2]int, error) {
return unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
}
nri-0.6.1/pkg/net/socketpair_cloexec_unix.go 0000664 0000000 0000000 00000001711 14610311645 0021116 0 ustar 00root root 0000000 0000000 //go:build !linux && !windows
/*
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 net
import (
"syscall"
"golang.org/x/sys/unix"
)
func newSocketPairCLOEXEC() ([2]int, error) {
syscall.ForkLock.RLock()
defer syscall.ForkLock.RUnlock()
fds, err := unix.Socketpair(unix.AF_UNIX, unix.SOCK_STREAM, 0)
if err != nil {
return fds, err
}
unix.CloseOnExec(fds[0])
unix.CloseOnExec(fds[1])
return fds, err
}
nri-0.6.1/pkg/net/socketpair_cloexec_windows.go 0000664 0000000 0000000 00000001652 14610311645 0021631 0 ustar 00root root 0000000 0000000 //go:build windows
/*
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 net
import (
"errors"
sys "golang.org/x/sys/windows"
)
func newSocketPairCLOEXEC() ([2]sys.Handle, error) {
// when implementing do use WSA_FLAG_NO_HANDLE_INHERIT to avoid leaking FDs
return [2]sys.Handle{sys.InvalidHandle, sys.InvalidHandle}, errors.New("newSocketPairCLOEXEC unimplemented for windows")
}
nri-0.6.1/pkg/net/socketpair_test.go 0000664 0000000 0000000 00000006262 14610311645 0017416 0 ustar 00root root 0000000 0000000 /*
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 net_test
import (
"bufio"
"errors"
"fmt"
"io"
"github.com/containerd/nri/pkg/net"
"testing"
require "github.com/stretchr/testify/require"
)
func TestNewSocketPair(t *testing.T) {
sp, err := net.NewSocketPair()
require.NoError(t, err, "NewSocketPair()")
require.NotNil(t, sp, "NewSocketPair()")
conn, err := sp.LocalConn()
require.NoError(t, err, "LocalConn()")
require.NotNil(t, conn, "LocalConn()")
conn, err = sp.PeerConn()
require.NoError(t, err, "PeerConn()")
require.NotNil(t, conn, "PeerConn()")
f := sp.LocalFile()
require.NotNil(t, f, "LocalFile()")
f = sp.PeerFile()
require.NotNil(t, f, "PeerFile()")
sp.Close()
}
func TestConnReadWrite(t *testing.T) {
sp, err := net.NewSocketPair()
require.NoError(t, err, "NewSocketPair()")
require.NotNil(t, sp, "NewSocketPair()")
conn, err := sp.LocalConn()
require.NoError(t, err, "LocalConn()")
require.NotNil(t, conn, "LocalConn()")
sent := []string{}
recv := []string{}
done := make(chan error, 1)
reader := func() {
conn, err := sp.PeerConn()
require.NoError(t, err, "PeerConn()")
require.NotNil(t, conn, "PeerConn()")
defer conn.Close()
buf := bufio.NewReader(conn)
for {
msg, err := buf.ReadString('\n')
if err != nil {
if !errors.Is(err, io.EOF) {
done <- fmt.Errorf("ReadString() failed: %w", err)
}
break
}
recv = append(recv, msg)
}
close(done)
}
go reader()
for i := 0; i < 32; i++ {
msg := fmt.Sprintf("message #%d\n", i)
_, err := conn.Write([]byte(msg))
require.NoError(t, err, "Write()")
sent = append(sent, msg)
}
conn.Close()
err = <-done
require.NoError(t, err, "done/reader")
require.Equal(t, sent, recv, "send and received data")
}
func TestFileReadWrite(t *testing.T) {
sp, err := net.NewSocketPair()
require.NoError(t, err, "NewSocketPair()")
require.NotNil(t, sp, "NewSocketPair()")
f := sp.LocalFile()
require.NotNil(t, f, "LocalFile()")
sent := []string{}
recv := []string{}
done := make(chan error, 1)
reader := func() {
f := sp.PeerFile()
require.NotNil(t, f, "PeerFile()")
defer f.Close()
buf := bufio.NewReader(f)
for {
msg, err := buf.ReadString('\n')
if err != nil {
if !errors.Is(err, io.EOF) {
done <- fmt.Errorf("ReadString(): %w", err)
}
break
}
recv = append(recv, msg)
}
close(done)
}
go reader()
for i := 0; i < 32; i++ {
msg := fmt.Sprintf("message #%d\n", i)
_, err := f.Write([]byte(msg))
require.NoError(t, err, "Write()")
sent = append(sent, msg)
}
f.Close()
err = <-done
require.NoError(t, err, "done/reader")
require.Equal(t, sent, recv, "send and received data")
}
nri-0.6.1/pkg/runtime-tools/ 0000775 0000000 0000000 00000000000 14610311645 0015711 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/runtime-tools/generate/ 0000775 0000000 0000000 00000000000 14610311645 0017503 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/runtime-tools/generate/generate.go 0000664 0000000 0000000 00000032601 14610311645 0021626 0 ustar 00root root 0000000 0000000 /*
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 generate
import (
"fmt"
"os"
"path/filepath"
"sort"
"strings"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/opencontainers/runtime-tools/generate"
nri "github.com/containerd/nri/pkg/api"
)
// GeneratorOption is an option for Generator().
type GeneratorOption func(*Generator)
// Generator extends a stock runtime-tools Generator and extends it with
// a few functions for handling NRI container adjustment.
type Generator struct {
*generate.Generator
filterLabels func(map[string]string) (map[string]string, error)
filterAnnotations func(map[string]string) (map[string]string, error)
resolveBlockIO func(string) (*rspec.LinuxBlockIO, error)
resolveRdt func(string) (*rspec.LinuxIntelRdt, error)
checkResources func(*rspec.LinuxResources) error
}
// SpecGenerator returns a wrapped OCI Spec Generator.
func SpecGenerator(gg *generate.Generator, opts ...GeneratorOption) *Generator {
g := &Generator{
Generator: gg,
}
g.filterLabels = nopFilter
g.filterAnnotations = nopFilter
for _, o := range opts {
o(g)
}
return g
}
// WithLabelFilter provides an option for filtering or rejecting labels.
func WithLabelFilter(fn func(map[string]string) (map[string]string, error)) GeneratorOption {
return func(g *Generator) {
g.filterLabels = fn
}
}
// WithAnnotationFilter provides an option for filtering or rejecting annotations.
func WithAnnotationFilter(fn func(map[string]string) (map[string]string, error)) GeneratorOption {
return func(g *Generator) {
g.filterAnnotations = fn
}
}
// WithBlockIOResolver specifies a function for resolving Block I/O classes by name.
func WithBlockIOResolver(fn func(string) (*rspec.LinuxBlockIO, error)) GeneratorOption {
return func(g *Generator) {
g.resolveBlockIO = fn
}
}
// WithRdtResolver specifies a function for resolving RDT classes by name.
func WithRdtResolver(fn func(string) (*rspec.LinuxIntelRdt, error)) GeneratorOption {
return func(g *Generator) {
g.resolveRdt = fn
}
}
// WithResourceChecker specifies a function to perform final resource adjustment.
func WithResourceChecker(fn func(*rspec.LinuxResources) error) GeneratorOption {
return func(g *Generator) {
g.checkResources = fn
}
}
// Adjust adjusts all aspects of the OCI Spec that NRI knows/cares about.
func (g *Generator) Adjust(adjust *nri.ContainerAdjustment) error {
if adjust == nil {
return nil
}
if err := g.AdjustAnnotations(adjust.GetAnnotations()); err != nil {
return fmt.Errorf("failed to adjust annotations in OCI Spec: %w", err)
}
g.AdjustEnv(adjust.GetEnv())
g.AdjustHooks(adjust.GetHooks())
g.AdjustDevices(adjust.GetLinux().GetDevices())
g.AdjustCgroupsPath(adjust.GetLinux().GetCgroupsPath())
resources := adjust.GetLinux().GetResources()
if err := g.AdjustResources(resources); err != nil {
return err
}
if err := g.AdjustBlockIOClass(resources.GetBlockioClass().Get()); err != nil {
return err
}
if err := g.AdjustRdtClass(resources.GetRdtClass().Get()); err != nil {
return err
}
if err := g.AdjustMounts(adjust.GetMounts()); err != nil {
return err
}
if err := g.AdjustRlimits(adjust.GetRlimits()); err != nil {
return err
}
return nil
}
// AdjustEnv adjusts the environment of the OCI Spec.
func (g *Generator) AdjustEnv(env []*nri.KeyValue) {
mod := map[string]*nri.KeyValue{}
for _, e := range env {
key, _ := nri.IsMarkedForRemoval(e.Key)
mod[key] = e
}
// first modify existing environment
if len(mod) > 0 && g.Config != nil && g.Config.Process != nil {
old := g.Config.Process.Env
g.ClearProcessEnv()
for _, e := range old {
keyval := strings.SplitN(e, "=", 2)
if len(keyval) < 2 {
continue
}
if m, ok := mod[keyval[0]]; ok {
delete(mod, keyval[0])
if _, marked := m.IsMarkedForRemoval(); !marked {
g.AddProcessEnv(m.Key, m.Value)
}
continue
}
g.AddProcessEnv(keyval[0], keyval[1])
}
}
// then append remaining unprocessed adjustments (new variables)
for _, e := range env {
if _, marked := e.IsMarkedForRemoval(); marked {
continue
}
if _, ok := mod[e.Key]; ok {
g.AddProcessEnv(e.Key, e.Value)
}
}
}
// AdjustAnnotations adjusts the annotations in the OCI Spec.
func (g *Generator) AdjustAnnotations(annotations map[string]string) error {
var err error
if annotations, err = g.filterAnnotations(annotations); err != nil {
return err
}
for k, v := range annotations {
if key, marked := nri.IsMarkedForRemoval(k); marked {
g.RemoveAnnotation(key)
} else {
g.AddAnnotation(k, v)
}
}
return nil
}
// AdjustHooks adjusts the OCI hooks in the OCI Spec.
func (g *Generator) AdjustHooks(hooks *nri.Hooks) {
if hooks == nil {
return
}
for _, h := range hooks.Prestart {
g.AddPreStartHook(h.ToOCI())
}
for _, h := range hooks.Poststart {
g.AddPostStartHook(h.ToOCI())
}
for _, h := range hooks.Poststop {
g.AddPostStopHook(h.ToOCI())
}
for _, h := range hooks.CreateRuntime {
g.AddCreateRuntimeHook(h.ToOCI())
}
for _, h := range hooks.CreateContainer {
g.AddCreateContainerHook(h.ToOCI())
}
for _, h := range hooks.StartContainer {
g.AddStartContainerHook(h.ToOCI())
}
}
// AdjustResources adjusts the (Linux) resources in the OCI Spec.
func (g *Generator) AdjustResources(r *nri.LinuxResources) error {
if r == nil {
return nil
}
g.initConfigLinux()
if r.Cpu != nil {
if r.Cpu.Period != nil {
g.SetLinuxResourcesCPUPeriod(r.Cpu.GetPeriod().GetValue())
}
if r.Cpu.Quota != nil {
g.SetLinuxResourcesCPUQuota(r.Cpu.GetQuota().GetValue())
}
if r.Cpu.Shares != nil {
g.SetLinuxResourcesCPUShares(r.Cpu.GetShares().GetValue())
}
if r.Cpu.Cpus != "" {
g.SetLinuxResourcesCPUCpus(r.Cpu.GetCpus())
}
if r.Cpu.Mems != "" {
g.SetLinuxResourcesCPUMems(r.Cpu.GetMems())
}
if r.Cpu.RealtimeRuntime != nil {
g.SetLinuxResourcesCPURealtimeRuntime(r.Cpu.GetRealtimeRuntime().GetValue())
}
if r.Cpu.RealtimePeriod != nil {
g.SetLinuxResourcesCPURealtimePeriod(r.Cpu.GetRealtimePeriod().GetValue())
}
}
if r.Memory != nil {
if l := r.Memory.GetLimit().GetValue(); l != 0 {
g.SetLinuxResourcesMemoryLimit(l)
g.SetLinuxResourcesMemorySwap(l)
}
}
for _, l := range r.HugepageLimits {
g.AddLinuxResourcesHugepageLimit(l.PageSize, l.Limit)
}
for k, v := range r.Unified {
g.AddLinuxResourcesUnified(k, v)
}
if g.checkResources != nil {
if err := g.checkResources(g.Config.Linux.Resources); err != nil {
return fmt.Errorf("failed to adjust resources in OCI Spec: %w", err)
}
}
return nil
}
// AdjustBlockIOClass adjusts the block I/O class in the OCI Spec.
func (g *Generator) AdjustBlockIOClass(blockIOClass *string) error {
if blockIOClass == nil || g.resolveBlockIO == nil {
return nil
}
if *blockIOClass == "" {
g.ClearLinuxResourcesBlockIO()
return nil
}
blockIO, err := g.resolveBlockIO(*blockIOClass)
if err != nil {
return fmt.Errorf("failed to adjust BlockIO class in OCI Spec: %w", err)
}
g.SetLinuxResourcesBlockIO(blockIO)
return nil
}
// AdjustRdtClass adjusts the RDT class in the OCI Spec.
func (g *Generator) AdjustRdtClass(rdtClass *string) error {
if rdtClass == nil || g.resolveRdt == nil {
return nil
}
if *rdtClass == "" {
g.ClearLinuxIntelRdt()
return nil
}
rdt, err := g.resolveRdt(*rdtClass)
if err != nil {
return fmt.Errorf("failed to adjust RDT class in OCI Spec: %w", err)
}
g.SetLinuxIntelRdt(rdt)
return nil
}
// AdjustCgroupsPath adjusts the cgroup pseudofs path in the OCI Spec.
func (g *Generator) AdjustCgroupsPath(path string) {
if path != "" {
g.SetLinuxCgroupsPath(path)
}
}
// AdjustDevices adjusts the (Linux) devices in the OCI Spec.
func (g *Generator) AdjustDevices(devices []*nri.LinuxDevice) {
for _, d := range devices {
key, marked := d.IsMarkedForRemoval()
g.RemoveDevice(key)
if marked {
continue
}
g.AddDevice(d.ToOCI())
major, minor, access := &d.Major, &d.Minor, d.AccessString()
g.AddLinuxResourcesDevice(true, d.Type, major, minor, access)
}
}
func (g *Generator) AdjustRlimits(rlimits []*nri.POSIXRlimit) error {
for _, l := range rlimits {
if l == nil {
continue
}
g.Config.Process.Rlimits = append(g.Config.Process.Rlimits, rspec.POSIXRlimit{
Type: l.Type,
Hard: l.Hard,
Soft: l.Soft,
})
}
return nil
}
// AdjustMounts adjusts the mounts in the OCI Spec.
func (g *Generator) AdjustMounts(mounts []*nri.Mount) error {
if len(mounts) == 0 {
return nil
}
propagation := ""
for _, m := range mounts {
if destination, marked := m.IsMarkedForRemoval(); marked {
g.RemoveMount(destination)
continue
}
g.RemoveMount(m.Destination)
mnt := m.ToOCI(&propagation)
switch propagation {
case "rprivate":
case "rshared":
if err := ensurePropagation(mnt.Source, "rshared"); err != nil {
return fmt.Errorf("failed to adjust mounts in OCI Spec: %w", err)
}
if err := g.SetLinuxRootPropagation("rshared"); err != nil {
return fmt.Errorf("failed to adjust rootfs propagation in OCI Spec: %w", err)
}
case "rslave":
if err := ensurePropagation(mnt.Source, "rshared", "rslave"); err != nil {
return fmt.Errorf("failed to adjust mounts in OCI Spec: %w", err)
}
rootProp := g.Config.Linux.RootfsPropagation
if rootProp != "rshared" && rootProp != "rslave" {
if err := g.SetLinuxRootPropagation("rslave"); err != nil {
return fmt.Errorf("failed to adjust rootfs propagation in OCI Spec: %w", err)
}
}
}
g.AddMount(mnt)
}
g.sortMounts()
return nil
}
// sortMounts sorts the mounts in the generated OCI Spec.
func (g *Generator) sortMounts() {
mounts := g.Generator.Mounts()
g.Generator.ClearMounts()
sort.Sort(orderedMounts(mounts))
// TODO(klihub): This is now a bit ugly maybe we should introduce a
// SetMounts([]rspec.Mount) to runtime-tools/generate.Generator. That
// could also take care of properly sorting the mount slice.
g.Generator.Config.Mounts = mounts
}
// orderedMounts defines how to sort an OCI Spec Mount slice.
// This is the almost the same implementation sa used by CRI-O and Docker,
// with a minor tweak for stable sorting order (easier to test):
//
// https://github.com/moby/moby/blob/17.05.x/daemon/volumes.go#L26
type orderedMounts []rspec.Mount
// Len returns the number of mounts. Used in sorting.
func (m orderedMounts) Len() int {
return len(m)
}
// Less returns true if the number of parts (a/b/c would be 3 parts) in the
// mount indexed by parameter 1 is less than that of the mount indexed by
// parameter 2. Used in sorting.
func (m orderedMounts) Less(i, j int) bool {
ip, jp := m.parts(i), m.parts(j)
if ip < jp {
return true
}
if jp < ip {
return false
}
return m[i].Destination < m[j].Destination
}
// Swap swaps two items in an array of mounts. Used in sorting
func (m orderedMounts) Swap(i, j int) {
m[i], m[j] = m[j], m[i]
}
// parts returns the number of parts in the destination of a mount. Used in sorting.
func (m orderedMounts) parts(i int) int {
return strings.Count(filepath.Clean(m[i].Destination), string(os.PathSeparator))
}
func nopFilter(m map[string]string) (map[string]string, error) {
return m, nil
}
//
// TODO: these could be added to the stock Spec generator...
//
// AddCreateRuntimeHook adds a hooks new CreateRuntime hooks.
func (g *Generator) AddCreateRuntimeHook(hook rspec.Hook) {
g.initConfigHooks()
g.Config.Hooks.CreateRuntime = append(g.Config.Hooks.CreateRuntime, hook)
}
// AddCreateContainerHook adds a hooks new CreateContainer hooks.
func (g *Generator) AddCreateContainerHook(hook rspec.Hook) {
g.initConfigHooks()
g.Config.Hooks.CreateContainer = append(g.Config.Hooks.CreateContainer, hook)
}
// AddStartContainerHook adds a hooks new StartContainer hooks.
func (g *Generator) AddStartContainerHook(hook rspec.Hook) {
g.initConfigHooks()
g.Config.Hooks.StartContainer = append(g.Config.Hooks.StartContainer, hook)
}
// ClearLinuxIntelRdt clears RDT CLOS.
func (g *Generator) ClearLinuxIntelRdt() {
g.initConfigLinux()
g.Config.Linux.IntelRdt = nil
}
// SetLinuxIntelRdt sets RDT CLOS.
func (g *Generator) SetLinuxIntelRdt(rdt *rspec.LinuxIntelRdt) {
g.initConfigLinux()
g.Config.Linux.IntelRdt = rdt
}
// ClearLinuxResourcesBlockIO clears Block I/O settings.
func (g *Generator) ClearLinuxResourcesBlockIO() {
g.initConfigLinuxResources()
g.Config.Linux.Resources.BlockIO = nil
}
// SetLinuxResourcesBlockIO sets Block I/O settings.
func (g *Generator) SetLinuxResourcesBlockIO(blockIO *rspec.LinuxBlockIO) {
g.initConfigLinuxResources()
g.Config.Linux.Resources.BlockIO = blockIO
}
func (g *Generator) initConfig() {
if g.Config == nil {
g.Config = &rspec.Spec{}
}
}
func (g *Generator) initConfigHooks() {
g.initConfig()
if g.Config.Hooks == nil {
g.Config.Hooks = &rspec.Hooks{}
}
}
func (g *Generator) initConfigLinux() {
g.initConfig()
if g.Config.Linux == nil {
g.Config.Linux = &rspec.Linux{}
}
}
func (g *Generator) initConfigLinuxResources() {
g.initConfigLinux()
if g.Config.Linux.Resources == nil {
g.Config.Linux.Resources = &rspec.LinuxResources{}
}
}
nri-0.6.1/pkg/runtime-tools/generate/generate_suite_test.go 0000664 0000000 0000000 00000023460 14610311645 0024101 0 ustar 00root root 0000000 0000000 /*
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 generate_test
import (
"testing"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
rspec "github.com/opencontainers/runtime-spec/specs-go"
rgen "github.com/opencontainers/runtime-tools/generate"
"github.com/containerd/nri/pkg/api"
xgen "github.com/containerd/nri/pkg/runtime-tools/generate"
)
func TestGenerate(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Generate Suite")
}
var _ = Describe("Adjustment", func() {
When("nil", func() {
It("does not modify the Spec", func() {
var (
spec = makeSpec()
adjust *api.ContainerAdjustment
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec()))
})
})
When("empty", func() {
It("does not modify the Spec", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec()))
})
})
When("has rlimits", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Rlimits: []*api.POSIXRlimit{{
Type: "nofile",
Hard: 456,
Soft: 123,
}},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withRlimit("nofile", 456, 123))))
})
})
When("has memory limit", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Memory: &api.LinuxMemory{
Limit: api.Int64(11111),
},
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withMemoryLimit(11111), withMemorySwap(11111))))
})
})
When("has CPU shares", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Shares: api.UInt64(11111),
},
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withCPUShares(11111))))
})
})
When("has CPU quota", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Quota: api.Int64(11111),
},
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withCPUQuota(11111))))
})
})
When("has CPU period", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Period: api.UInt64(11111),
},
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withCPUPeriod(11111))))
})
})
When("has cpuset CPUs", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Cpus: "5,6",
},
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withCPUSetCPUs("5,6"))))
})
})
When("has cpuset mems", func() {
It("adjusts Spec correctly", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Linux: &api.LinuxContainerAdjustment{
Resources: &api.LinuxResources{
Cpu: &api.LinuxCPU{
Mems: "5,6",
},
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(withCPUSetMems("5,6"))))
})
})
When("has mounts", func() {
It("it sorts the Spec mount slice", func() {
var (
spec = makeSpec()
adjust = &api.ContainerAdjustment{
Mounts: []*api.Mount{
{
Destination: "/a/b/c/d/e",
Source: "/host/e",
},
{
Destination: "/a/b/c",
Source: "/host/c",
},
{
Destination: "/a/b",
Source: "/host/b",
},
{
Destination: "/a",
Source: "/host/a",
},
},
}
)
rg := &rgen.Generator{Config: spec}
xg := xgen.SpecGenerator(rg)
Expect(xg).ToNot(BeNil())
Expect(xg.Adjust(adjust)).To(Succeed())
Expect(spec).To(Equal(makeSpec(
withMounts([]rspec.Mount{
{
Destination: "/a",
Source: "/host/a",
},
{
Destination: "/a/b",
Source: "/host/b",
},
{
Destination: "/a/b/c",
Source: "/host/c",
},
{
Destination: "/a/b/c/d/e",
Source: "/host/e",
},
}),
)))
})
})
})
type specOption func(*rspec.Spec)
func withMemoryLimit(v int64) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
if spec.Linux.Resources.Memory == nil {
spec.Linux.Resources.Memory = &rspec.LinuxMemory{}
}
spec.Linux.Resources.Memory.Limit = &v
}
}
func withMemorySwap(v int64) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
if spec.Linux.Resources.Memory == nil {
spec.Linux.Resources.Memory = &rspec.LinuxMemory{}
}
spec.Linux.Resources.Memory.Swap = &v
}
}
func withCPUShares(v uint64) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
if spec.Linux.Resources.CPU == nil {
spec.Linux.Resources.CPU = &rspec.LinuxCPU{}
}
spec.Linux.Resources.CPU.Shares = &v
}
}
func withCPUQuota(v int64) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
if spec.Linux.Resources.CPU == nil {
spec.Linux.Resources.CPU = &rspec.LinuxCPU{}
}
spec.Linux.Resources.CPU.Quota = &v
}
}
func withCPUPeriod(v uint64) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
if spec.Linux.Resources.CPU == nil {
spec.Linux.Resources.CPU = &rspec.LinuxCPU{}
}
spec.Linux.Resources.CPU.Period = &v
}
}
func withCPUSetCPUs(v string) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
if spec.Linux.Resources.CPU == nil {
spec.Linux.Resources.CPU = &rspec.LinuxCPU{}
}
spec.Linux.Resources.CPU.Cpus = v
}
}
func withCPUSetMems(v string) specOption {
return func(spec *rspec.Spec) {
if spec.Linux == nil {
spec.Linux = &rspec.Linux{}
}
if spec.Linux.Resources == nil {
spec.Linux.Resources = &rspec.LinuxResources{}
}
if spec.Linux.Resources.CPU == nil {
spec.Linux.Resources.CPU = &rspec.LinuxCPU{}
}
spec.Linux.Resources.CPU.Mems = v
}
}
func withMounts(mounts []rspec.Mount) specOption {
return func(spec *rspec.Spec) {
spec.Mounts = append(spec.Mounts, mounts...)
}
}
func withRlimit(typ string, hard, soft uint64) specOption {
return func(spec *rspec.Spec) {
if spec.Process == nil {
return
}
spec.Process.Rlimits = append(spec.Process.Rlimits, rspec.POSIXRlimit{
Type: typ,
Hard: hard,
Soft: soft,
})
}
}
func makeSpec(options ...specOption) *rspec.Spec {
spec := &rspec.Spec{
Process: &rspec.Process{},
Linux: &rspec.Linux{
Resources: &rspec.LinuxResources{
Memory: &rspec.LinuxMemory{
Limit: Int64(12345),
},
CPU: &rspec.LinuxCPU{
Shares: Uint64(45678),
Quota: Int64(87654),
Period: Uint64(54321),
Cpus: "0-111",
Mems: "0-4",
},
},
},
}
for _, o := range options {
o(spec)
}
return spec
}
func Int64(v int64) *int64 {
return &v
}
func Uint64(v uint64) *uint64 {
return &v
}
nri-0.6.1/pkg/runtime-tools/generate/helpers_linux.go 0000664 0000000 0000000 00000003214 14610311645 0022713 0 ustar 00root root 0000000 0000000 //go:build linux
/*
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 generate
import (
"fmt"
"path/filepath"
"strings"
"github.com/moby/sys/mountinfo"
)
func getPropagation(path string) (string, error) {
var (
dir = filepath.Clean(path)
mnt *mountinfo.Info
)
mounts, err := mountinfo.GetMounts(mountinfo.ParentsFilter(dir))
if err != nil {
return "", err
}
if len(mounts) == 0 {
return "", fmt.Errorf("failed to get mount info for %q", path)
}
maxLen := 0
for _, m := range mounts {
if l := len(m.Mountpoint); l > maxLen {
mnt = m
maxLen = l
}
}
for _, opt := range strings.Split(mnt.Optional, " ") {
switch {
case strings.HasPrefix(opt, "shared:"):
return "rshared", nil
case strings.HasPrefix(opt, "master:"):
return "rslave", nil
}
}
return "", nil
}
func ensurePropagation(path string, accepted ...string) error {
prop, err := getPropagation(path)
if err != nil {
return err
}
for _, p := range accepted {
if p == prop {
return nil
}
}
return fmt.Errorf("path %q mount propagation is %q, not %q",
path, prop, strings.Join(accepted, " or "))
}
nri-0.6.1/pkg/runtime-tools/generate/helpers_other.go 0000664 0000000 0000000 00000001307 14610311645 0022676 0 ustar 00root root 0000000 0000000 //go:build !linux
/*
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 generate
func ensurePropagation(path string, accepted ...string) error {
return nil
}
nri-0.6.1/pkg/stub/ 0000775 0000000 0000000 00000000000 14610311645 0014045 5 ustar 00root root 0000000 0000000 nri-0.6.1/pkg/stub/stub.go 0000664 0000000 0000000 00000053700 14610311645 0015356 0 ustar 00root root 0000000 0000000 /*
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 stub
import (
"context"
"errors"
"fmt"
stdnet "net"
"os"
"path/filepath"
"strconv"
"sync"
"time"
"github.com/containerd/nri/pkg/api"
nrilog "github.com/containerd/nri/pkg/log"
"github.com/containerd/nri/pkg/net"
"github.com/containerd/nri/pkg/net/multiplex"
"github.com/containerd/ttrpc"
)
// Plugin can implement a number of interfaces related to Pod and Container
// lifecycle events. No any single such inteface is mandatory, therefore the
// Plugin interface itself is empty. Plugins are required to implement at
// least one of these interfaces and this is verified during stub creation.
// Trying to create a stub for a plugin violating this requirement will fail
// with and error.
type Plugin interface{}
// ConfigureInterface handles Configure API request.
type ConfigureInterface interface {
// Configure the plugin with the given NRI-supplied configuration.
// If a non-zero EventMask is returned, the plugin will be subscribed
// to the corresponding.
Configure(ctx context.Context, config, runtime, version string) (api.EventMask, error)
}
// SynchronizeInterface handles Synchronize API requests.
type SynchronizeInterface interface {
// Synchronize the state of the plugin with the runtime.
// The plugin can request updates to containers in response.
Synchronize(context.Context, []*api.PodSandbox, []*api.Container) ([]*api.ContainerUpdate, error)
}
// ShutdownInterface handles a Shutdown API request.
type ShutdownInterface interface {
// Shutdown notifies the plugin about the runtime shutting down.
Shutdown(context.Context)
}
// RunPodInterface handles RunPodSandbox API events.
type RunPodInterface interface {
// RunPodSandbox relays a RunPodSandbox event to the plugin.
RunPodSandbox(context.Context, *api.PodSandbox) error
}
// StopPodInterface handles StopPodSandbox API events.
type StopPodInterface interface {
// StopPodSandbox relays a StopPodSandbox event to the plugin.
StopPodSandbox(context.Context, *api.PodSandbox) error
}
// RemovePodInterface handles RemovePodSandbox API events.
type RemovePodInterface interface {
// RemovePodSandbox relays a RemovePodSandbox event to the plugin.
RemovePodSandbox(context.Context, *api.PodSandbox) error
}
// CreateContainerInterface handles CreateContainer API requests.
type CreateContainerInterface interface {
// CreateContainer relays a CreateContainer request to the plugin.
// The plugin can request adjustments to the container being created
// and updates to other unstopped containers in response.
CreateContainer(context.Context, *api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error)
}
// StartContainerInterface handles StartContainer API requests.
type StartContainerInterface interface {
// StartContainer relays a StartContainer event to the plugin.
StartContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// UpdateContainerInterface handles UpdateContainer API requests.
type UpdateContainerInterface interface {
// UpdateContainer relays an UpdateContainer request to the plugin.
// The plugin can request updates both to the container being updated
// (which then supersedes the original update) and to other unstopped
// containers in response.
UpdateContainer(context.Context, *api.PodSandbox, *api.Container, *api.LinuxResources) ([]*api.ContainerUpdate, error)
}
// StopContainerInterface handles StopContainer API requests.
type StopContainerInterface interface {
// StopContainer relays a StopContainer request to the plugin.
// The plugin can request updates to unstopped containers in response.
StopContainer(context.Context, *api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
}
// RemoveContainerInterface handles RemoveContainer API events.
type RemoveContainerInterface interface {
// RemoveContainer relays a RemoveContainer event to the plugin.
RemoveContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// PostCreateContainerInterface handles PostCreateContainer API events.
type PostCreateContainerInterface interface {
// PostCreateContainer relays a PostCreateContainer event to the plugin.
PostCreateContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// PostStartContainerInterface handles PostStartContainer API events.
type PostStartContainerInterface interface {
// PostStartContainer relays a PostStartContainer event to the plugin.
PostStartContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// PostUpdateContainerInterface handles PostUpdateContainer API events.
type PostUpdateContainerInterface interface {
// PostUpdateContainer relays a PostUpdateContainer event to the plugin.
PostUpdateContainer(context.Context, *api.PodSandbox, *api.Container) error
}
// Stub is the interface the stub provides for the plugin implementation.
type Stub interface {
// Run the plugin. Starts the plugin then waits for an error or the plugin to stop
Run(context.Context) error
// Start the plugin.
Start(context.Context) error
// Stop the plugin.
Stop()
// Wait for the plugin to stop.
Wait()
// UpdateContainer requests unsolicited updates to containers.
UpdateContainers([]*api.ContainerUpdate) ([]*api.ContainerUpdate, error)
}
const (
// Plugin registration timeout.
registrationTimeout = 2 * time.Second
)
var (
// Logger for messages generated internally by the stub itself.
log = nrilog.Get()
// Used instead of a nil Context in logging.
noCtx = context.TODO()
// ErrNoService indicates that the stub has no runtime service/connection,
// for instance by UpdateContainers on a stub which has not been started.
ErrNoService = errors.New("stub: no service/connection")
)
// EventMask holds a mask of events for plugin subscription.
type EventMask = api.EventMask
// Option to apply to a plugin during its creation.
type Option func(*stub) error
// WithOnClose sets a notification function to call if the ttRPC connection goes down.
func WithOnClose(onClose func()) Option {
return func(s *stub) error {
s.onClose = onClose
return nil
}
}
// WithPluginName sets the name to use in plugin registration.
func WithPluginName(name string) Option {
return func(s *stub) error {
if s.name != "" {
return fmt.Errorf("plugin name already set (%q)", s.name)
}
s.name = name
return nil
}
}
// WithPluginIdx sets the index to use in plugin registration.
func WithPluginIdx(idx string) Option {
return func(s *stub) error {
if s.idx != "" {
return fmt.Errorf("plugin ID already set (%q)", s.idx)
}
s.idx = idx
return nil
}
}
// WithSocketPath sets the NRI socket path to connect to.
func WithSocketPath(path string) Option {
return func(s *stub) error {
s.socketPath = path
return nil
}
}
// WithConnection sets an existing NRI connection to use.
func WithConnection(conn stdnet.Conn) Option {
return func(s *stub) error {
s.conn = conn
return nil
}
}
// WithDialer sets the dialer to use.
func WithDialer(d func(string) (stdnet.Conn, error)) Option {
return func(s *stub) error {
s.dialer = d
return nil
}
}
// WithTTRPCOptions sets extra client and server options to use for ttrpc .
func WithTTRPCOptions(clientOpts []ttrpc.ClientOpts, serverOpts []ttrpc.ServerOpt) Option {
return func(s *stub) error {
s.clientOpts = append(s.clientOpts, clientOpts...)
s.serverOpts = append(s.serverOpts, serverOpts...)
return nil
}
}
// stub implements Stub.
type stub struct {
sync.Mutex
plugin interface{}
handlers handlers
events api.EventMask
name string
idx string
socketPath string
dialer func(string) (stdnet.Conn, error)
conn stdnet.Conn
onClose func()
serverOpts []ttrpc.ServerOpt
clientOpts []ttrpc.ClientOpts
rpcm multiplex.Mux
rpcl stdnet.Listener
rpcs *ttrpc.Server
rpcc *ttrpc.Client
runtime api.RuntimeService
closeOnce sync.Once
started bool
doneC chan struct{}
srvErrC chan error
cfgErrC chan error
}
// Handlers for NRI plugin event and request.
type handlers struct {
Configure func(context.Context, string, string, string) (api.EventMask, error)
Synchronize func(context.Context, []*api.PodSandbox, []*api.Container) ([]*api.ContainerUpdate, error)
Shutdown func(context.Context)
RunPodSandbox func(context.Context, *api.PodSandbox) error
StopPodSandbox func(context.Context, *api.PodSandbox) error
RemovePodSandbox func(context.Context, *api.PodSandbox) error
CreateContainer func(context.Context, *api.PodSandbox, *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error)
StartContainer func(context.Context, *api.PodSandbox, *api.Container) error
UpdateContainer func(context.Context, *api.PodSandbox, *api.Container, *api.LinuxResources) ([]*api.ContainerUpdate, error)
StopContainer func(context.Context, *api.PodSandbox, *api.Container) ([]*api.ContainerUpdate, error)
RemoveContainer func(context.Context, *api.PodSandbox, *api.Container) error
PostCreateContainer func(context.Context, *api.PodSandbox, *api.Container) error
PostStartContainer func(context.Context, *api.PodSandbox, *api.Container) error
PostUpdateContainer func(context.Context, *api.PodSandbox, *api.Container) error
}
// New creates a stub with the given plugin and options.
func New(p interface{}, opts ...Option) (Stub, error) {
stub := &stub{
plugin: p,
name: os.Getenv(api.PluginNameEnvVar),
idx: os.Getenv(api.PluginIdxEnvVar),
socketPath: api.DefaultSocketPath,
dialer: func(p string) (stdnet.Conn, error) { return stdnet.Dial("unix", p) },
doneC: make(chan struct{}),
}
for _, o := range opts {
if err := o(stub); err != nil {
return nil, err
}
}
if err := stub.setupHandlers(); err != nil {
return nil, err
}
if err := stub.ensureIdentity(); err != nil {
return nil, err
}
log.Infof(noCtx, "Created plugin %s (%s, handles %s)", stub.Name(),
filepath.Base(os.Args[0]), stub.events.PrettyString())
return stub, nil
}
// Start event processing, register to NRI and wait for getting configured.
func (stub *stub) Start(ctx context.Context) (retErr error) {
stub.Lock()
defer stub.Unlock()
if stub.started {
return fmt.Errorf("stub already started")
}
stub.started = true
err := stub.connect()
if err != nil {
return err
}
rpcm := multiplex.Multiplex(stub.conn)
defer func() {
if retErr != nil {
rpcm.Close()
stub.rpcm = nil
}
}()
rpcl, err := rpcm.Listen(multiplex.PluginServiceConn)
if err != nil {
return err
}
defer func() {
if retErr != nil {
rpcl.Close()
stub.rpcl = nil
}
}()
rpcs, err := ttrpc.NewServer(stub.serverOpts...)
if err != nil {
return fmt.Errorf("failed to create ttrpc server: %w", err)
}
defer func() {
if retErr != nil {
rpcs.Close()
stub.rpcs = nil
}
}()
api.RegisterPluginService(rpcs, stub)
conn, err := rpcm.Open(multiplex.RuntimeServiceConn)
if err != nil {
return fmt.Errorf("failed to multiplex ttrpc client connection: %w", err)
}
clientOpts := []ttrpc.ClientOpts{
ttrpc.WithOnClose(func() {
stub.connClosed()
}),
}
rpcc := ttrpc.NewClient(conn, append(clientOpts, stub.clientOpts...)...)
defer func() {
if retErr != nil {
rpcc.Close()
stub.rpcc = nil
}
}()
stub.srvErrC = make(chan error, 1)
stub.cfgErrC = make(chan error, 1)
go func() {
stub.srvErrC <- rpcs.Serve(ctx, rpcl)
close(stub.doneC)
}()
stub.rpcm = rpcm
stub.rpcl = rpcl
stub.rpcs = rpcs
stub.rpcc = rpcc
stub.runtime = api.NewRuntimeClient(rpcc)
if err = stub.register(ctx); err != nil {
stub.close()
return err
}
if err = <-stub.cfgErrC; err != nil {
return err
}
log.Infof(ctx, "Started plugin %s...", stub.Name())
return nil
}
// Stop the plugin.
func (stub *stub) Stop() {
log.Infof(noCtx, "Stopping plugin %s...", stub.Name())
stub.Lock()
defer stub.Unlock()
stub.close()
}
func (stub *stub) close() {
stub.closeOnce.Do(func() {
if stub.rpcl != nil {
stub.rpcl.Close()
}
if stub.rpcs != nil {
stub.rpcs.Close()
}
if stub.rpcc != nil {
stub.rpcc.Close()
}
if stub.rpcm != nil {
stub.rpcm.Close()
}
if stub.srvErrC != nil {
<-stub.doneC
}
})
}
// Run the plugin. Start event processing then wait for an error or getting stopped.
func (stub *stub) Run(ctx context.Context) error {
var err error
if err = stub.Start(ctx); err != nil {
return err
}
err = <-stub.srvErrC
if err == ttrpc.ErrServerClosed {
return nil
}
return err
}
// Wait for the plugin to stop.
func (stub *stub) Wait() {
stub.Lock()
if stub.srvErrC == nil {
return
}
stub.Unlock()
<-stub.doneC
}
// Name returns the full indexed name of the plugin.
func (stub *stub) Name() string {
return stub.idx + "-" + stub.name
}
// Connect the plugin to NRI.
func (stub *stub) connect() error {
if stub.conn != nil {
log.Infof(noCtx, "Using given plugin connection...")
return nil
}
if env := os.Getenv(api.PluginSocketEnvVar); env != "" {
log.Infof(noCtx, "Using connection %q from environment...", env)
fd, err := strconv.Atoi(env)
if err != nil {
return fmt.Errorf("invalid socket in environment (%s=%q): %w",
api.PluginSocketEnvVar, env, err)
}
stub.conn, err = net.NewFdConn(fd)
if err != nil {
return fmt.Errorf("invalid socket (%d) in environment: %w", fd, err)
}
return nil
}
conn, err := stub.dialer(stub.socketPath)
if err != nil {
return fmt.Errorf("failed to connect to NRI service: %w", err)
}
stub.conn = conn
return nil
}
// Register the plugin with NRI.
func (stub *stub) register(ctx context.Context) error {
log.Infof(ctx, "Registering plugin %s...", stub.Name())
ctx, cancel := context.WithTimeout(ctx, registrationTimeout)
defer cancel()
req := &api.RegisterPluginRequest{
PluginName: stub.name,
PluginIdx: stub.idx,
}
if _, err := stub.runtime.RegisterPlugin(ctx, req); err != nil {
return fmt.Errorf("failed to register with NRI/Runtime: %w", err)
}
return nil
}
// Handle a lost connection.
func (stub *stub) connClosed() {
stub.close()
if stub.onClose != nil {
stub.onClose()
return
}
os.Exit(0)
}
//
// plugin event and request handlers
//
// UpdateContainers requests unsolicited updates to containers.
func (stub *stub) UpdateContainers(update []*api.ContainerUpdate) ([]*api.ContainerUpdate, error) {
if stub.runtime == nil {
return nil, ErrNoService
}
ctx := context.Background()
req := &api.UpdateContainersRequest{
Update: update,
}
rpl, err := stub.runtime.UpdateContainers(ctx, req)
if rpl != nil {
return rpl.Failed, err
}
return nil, err
}
// Configure the plugin.
func (stub *stub) Configure(ctx context.Context, req *api.ConfigureRequest) (rpl *api.ConfigureResponse, retErr error) {
var (
events api.EventMask
err error
)
log.Infof(ctx, "Configuring plugin %s for runtime %s/%s...", stub.Name(),
req.RuntimeName, req.RuntimeVersion)
defer func() {
stub.cfgErrC <- retErr
}()
if handler := stub.handlers.Configure; handler == nil {
events = stub.events
} else {
events, err = handler(ctx, req.Config, req.RuntimeName, req.RuntimeVersion)
if err != nil {
log.Errorf(ctx, "Plugin configuration failed: %v", err)
return nil, err
}
if events == 0 {
events = stub.events
}
// Only allow plugins to subscribe to events they can handle.
if extra := events & ^stub.events; extra != 0 {
log.Errorf(ctx, "Plugin subscribed for unhandled events %s (0x%x)",
extra.PrettyString(), extra)
return nil, fmt.Errorf("internal error: unhandled events %s (0x%x)",
extra.PrettyString(), extra)
}
log.Infof(ctx, "Subscribing plugin %s (%s) for events %s", stub.Name(),
filepath.Base(os.Args[0]), events.PrettyString())
}
return &api.ConfigureResponse{
Events: int32(events),
}, nil
}
// Synchronize the state of the plugin with the runtime.
func (stub *stub) Synchronize(ctx context.Context, req *api.SynchronizeRequest) (*api.SynchronizeResponse, error) {
handler := stub.handlers.Synchronize
if handler == nil {
return &api.SynchronizeResponse{}, nil
}
update, err := handler(ctx, req.Pods, req.Containers)
return &api.SynchronizeResponse{
Update: update,
}, err
}
// Shutdown the plugin.
func (stub *stub) Shutdown(ctx context.Context, req *api.ShutdownRequest) (*api.ShutdownResponse, error) {
handler := stub.handlers.Shutdown
if handler != nil {
handler(ctx)
}
return &api.ShutdownResponse{}, nil
}
// CreateContainer request handler.
func (stub *stub) CreateContainer(ctx context.Context, req *api.CreateContainerRequest) (*api.CreateContainerResponse, error) {
handler := stub.handlers.CreateContainer
if handler == nil {
return nil, nil
}
adjust, update, err := handler(ctx, req.Pod, req.Container)
return &api.CreateContainerResponse{
Adjust: adjust,
Update: update,
}, err
}
// UpdateContainer request handler.
func (stub *stub) UpdateContainer(ctx context.Context, req *api.UpdateContainerRequest) (*api.UpdateContainerResponse, error) {
handler := stub.handlers.UpdateContainer
if handler == nil {
return nil, nil
}
update, err := handler(ctx, req.Pod, req.Container, req.LinuxResources)
return &api.UpdateContainerResponse{
Update: update,
}, err
}
// StopContainer request handler.
func (stub *stub) StopContainer(ctx context.Context, req *api.StopContainerRequest) (*api.StopContainerResponse, error) {
handler := stub.handlers.StopContainer
if handler == nil {
return nil, nil
}
update, err := handler(ctx, req.Pod, req.Container)
return &api.StopContainerResponse{
Update: update,
}, err
}
// StateChange event handler.
func (stub *stub) StateChange(ctx context.Context, evt *api.StateChangeEvent) (*api.Empty, error) {
var err error
switch evt.Event {
case api.Event_RUN_POD_SANDBOX:
if handler := stub.handlers.RunPodSandbox; handler != nil {
err = handler(ctx, evt.Pod)
}
case api.Event_STOP_POD_SANDBOX:
if handler := stub.handlers.StopPodSandbox; handler != nil {
err = handler(ctx, evt.Pod)
}
case api.Event_REMOVE_POD_SANDBOX:
if handler := stub.handlers.RemovePodSandbox; handler != nil {
err = handler(ctx, evt.Pod)
}
case api.Event_POST_CREATE_CONTAINER:
if handler := stub.handlers.PostCreateContainer; handler != nil {
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_START_CONTAINER:
if handler := stub.handlers.StartContainer; handler != nil {
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_POST_START_CONTAINER:
if handler := stub.handlers.PostStartContainer; handler != nil {
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_POST_UPDATE_CONTAINER:
if handler := stub.handlers.PostUpdateContainer; handler != nil {
err = handler(ctx, evt.Pod, evt.Container)
}
case api.Event_REMOVE_CONTAINER:
if handler := stub.handlers.RemoveContainer; handler != nil {
err = handler(ctx, evt.Pod, evt.Container)
}
}
return &api.StateChangeResponse{}, err
}
// ensureIdentity sets plugin index and name from the binary if those are unset.
func (stub *stub) ensureIdentity() error {
if stub.idx != "" && stub.name != "" {
return nil
}
if stub.idx != "" {
stub.name = filepath.Base(os.Args[0])
return nil
}
idx, name, err := api.ParsePluginName(filepath.Base(os.Args[0]))
if err != nil {
return err
}
stub.name = name
stub.idx = idx
return nil
}
// Set up event handlers and the subscription mask for the plugin.
func (stub *stub) setupHandlers() error {
if plugin, ok := stub.plugin.(ConfigureInterface); ok {
stub.handlers.Configure = plugin.Configure
}
if plugin, ok := stub.plugin.(SynchronizeInterface); ok {
stub.handlers.Synchronize = plugin.Synchronize
}
if plugin, ok := stub.plugin.(ShutdownInterface); ok {
stub.handlers.Shutdown = plugin.Shutdown
}
if plugin, ok := stub.plugin.(RunPodInterface); ok {
stub.handlers.RunPodSandbox = plugin.RunPodSandbox
stub.events.Set(api.Event_RUN_POD_SANDBOX)
}
if plugin, ok := stub.plugin.(StopPodInterface); ok {
stub.handlers.StopPodSandbox = plugin.StopPodSandbox
stub.events.Set(api.Event_STOP_POD_SANDBOX)
}
if plugin, ok := stub.plugin.(RemovePodInterface); ok {
stub.handlers.RemovePodSandbox = plugin.RemovePodSandbox
stub.events.Set(api.Event_REMOVE_POD_SANDBOX)
}
if plugin, ok := stub.plugin.(CreateContainerInterface); ok {
stub.handlers.CreateContainer = plugin.CreateContainer
stub.events.Set(api.Event_CREATE_CONTAINER)
}
if plugin, ok := stub.plugin.(StartContainerInterface); ok {
stub.handlers.StartContainer = plugin.StartContainer
stub.events.Set(api.Event_START_CONTAINER)
}
if plugin, ok := stub.plugin.(UpdateContainerInterface); ok {
stub.handlers.UpdateContainer = plugin.UpdateContainer
stub.events.Set(api.Event_UPDATE_CONTAINER)
}
if plugin, ok := stub.plugin.(StopContainerInterface); ok {
stub.handlers.StopContainer = plugin.StopContainer
stub.events.Set(api.Event_STOP_CONTAINER)
}
if plugin, ok := stub.plugin.(RemoveContainerInterface); ok {
stub.handlers.RemoveContainer = plugin.RemoveContainer
stub.events.Set(api.Event_REMOVE_CONTAINER)
}
if plugin, ok := stub.plugin.(PostCreateContainerInterface); ok {
stub.handlers.PostCreateContainer = plugin.PostCreateContainer
stub.events.Set(api.Event_POST_CREATE_CONTAINER)
}
if plugin, ok := stub.plugin.(PostStartContainerInterface); ok {
stub.handlers.PostStartContainer = plugin.PostStartContainer
stub.events.Set(api.Event_POST_START_CONTAINER)
}
if plugin, ok := stub.plugin.(PostUpdateContainerInterface); ok {
stub.handlers.PostUpdateContainer = plugin.PostUpdateContainer
stub.events.Set(api.Event_POST_UPDATE_CONTAINER)
}
if stub.events == 0 {
return fmt.Errorf("internal error: plugin %T does not implement any NRI request handlers",
stub.plugin)
}
return nil
}
nri-0.6.1/plugins/ 0000775 0000000 0000000 00000000000 14610311645 0013770 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/device-injector/ 0000775 0000000 0000000 00000000000 14610311645 0017042 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/device-injector/README.md 0000664 0000000 0000000 00000002652 14610311645 0020326 0 ustar 00root root 0000000 0000000 ## Device Injector Plugin
This sample plugin can inject devices and mounts into containers using
pod annotations.
### Device Annotations
Devices are annotated using the `devices.nri.io` annotation key prefix.
The key `devices.nri.io/container.$CONTAINER_NAME` annotates devices to
be injected into `$CONTAINER_NAME`. The keys `devices.nri.io` and
`devices.nri.io/pod` annotate devices to inject into all containers.
The annotation syntax for device injection is
```
- path: /dev/dev0
type: {c|b}
major: 1
minor: 3
file_mode:
uid:
gid:
- path: /dev/dev1
...
```
`file_mode`, `uid` and `gid` can be omitted, the rest are mandatory.
### Mount Annotations
Mounts are annotated in a similar manner to devices, but using the
`mounts.nri.io` annotation key prefix. The annotation syntax for mount
injection is
```
- source:
destination:
type:
options:
- option0
option1
...
- source:
...
```
## Testing
You can test this plugin using a kubernetes cluster/node with a container
runtime that has NRI support enabled. Start the plugin on the target node
(`device-injector -idx 10`), create a pod with some annotated devices or
mounts, then verify that those get injected to the containers according
to the annotations. See the [sample pod spec](sample-device-inject.yaml)
for an example. nri-0.6.1/plugins/device-injector/device-injector.go 0000664 0000000 0000000 00000015023 14610311645 0022444 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
)
const (
// Prefix of the key used for device annotations.
deviceKey = "devices.nri.io"
// Prefix of the key used for mount annotations.
mountKey = "mounts.nri.io"
)
var (
log *logrus.Logger
verbose bool
)
// an annotated device
type device struct {
Path string `json:"path"`
Type string `json:"type"`
Major int64 `json:"major"`
Minor int64 `json:"minor"`
FileMode uint32 `json:"file_mode"`
UID uint32 `json:"uid"`
GID uint32 `json:"gid"`
}
// an annotated mount
type mount struct {
Source string `json:"source"`
Destination string `json:"destination"`
Type string `json:"type"`
Options []string `json:"options"`
}
// our injector plugin
type plugin struct {
stub stub.Stub
}
// CreateContainer handles container creation requests.
func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
var (
ctrName string
devices []device
mounts []mount
err error
)
ctrName = containerName(pod, container)
if verbose {
dump("CreateContainer", "pod", pod, "container", container)
}
adjust := &api.ContainerAdjustment{}
// inject devices to container
devices, err = parseDevices(container.Name, pod.Annotations)
if err != nil {
return nil, nil, err
}
if len(devices) == 0 {
log.Infof("%s: no devices annotated...", ctrName)
} else {
if verbose {
dump(ctrName, "annotated devices", devices)
}
for _, d := range devices {
adjust.AddDevice(d.toNRI())
if !verbose {
log.Infof("%s: injected device %q...", ctrName, d.Path)
}
}
}
// inject mounts to container
mounts, err = parseMounts(container.Name, pod.Annotations)
if err != nil {
return nil, nil, err
}
if len(mounts) == 0 {
log.Infof("%s: no mounts annotated...", ctrName)
} else {
if verbose {
dump(ctrName, "annotated mounts", mounts)
}
for _, m := range mounts {
adjust.AddMount(m.toNRI())
if !verbose {
log.Infof("%s: injected mount %q -> %q...", ctrName, m.Source, m.Destination)
}
}
}
if verbose {
dump(ctrName, "ContainerAdjustment", adjust)
}
return adjust, nil, nil
}
func parseDevices(ctr string, annotations map[string]string) ([]device, error) {
var (
key string
annotation []byte
devices []device
)
// look up effective device annotation and unmarshal devices
for _, key = range []string{
deviceKey + "/container." + ctr,
deviceKey + "/pod",
deviceKey,
} {
if value, ok := annotations[key]; ok {
annotation = []byte(value)
break
}
}
if annotation == nil {
return nil, nil
}
if err := yaml.Unmarshal(annotation, &devices); err != nil {
return nil, fmt.Errorf("invalid device annotation %q: %w", key, err)
}
return devices, nil
}
func parseMounts(ctr string, annotations map[string]string) ([]mount, error) {
var (
key string
annotation []byte
mounts []mount
)
// look up effective device annotation and unmarshal devices
for _, key = range []string{
mountKey + "/container." + ctr,
mountKey + "/pod",
mountKey,
} {
if value, ok := annotations[key]; ok {
annotation = []byte(value)
break
}
}
if annotation == nil {
return nil, nil
}
if err := yaml.Unmarshal(annotation, &mounts); err != nil {
return nil, fmt.Errorf("invalid mount annotation %q: %w", key, err)
}
return mounts, nil
}
// Convert a device to the NRI API representation.
func (d *device) toNRI() *api.LinuxDevice {
apiDev := &api.LinuxDevice{
Path: d.Path,
Type: d.Type,
Major: d.Major,
Minor: d.Minor,
}
if d.FileMode != 0 {
apiDev.FileMode = api.FileMode(d.FileMode)
}
if d.UID != 0 {
apiDev.Uid = api.UInt32(d.UID)
}
if d.GID != 0 {
apiDev.Gid = api.UInt32(d.GID)
}
return apiDev
}
// Convert a device to the NRI API representation.
func (m *mount) toNRI() *api.Mount {
apiMnt := &api.Mount{
Source: m.Source,
Destination: m.Destination,
Type: m.Type,
Options: m.Options,
}
return apiMnt
}
// Construct a container name for log messages.
func containerName(pod *api.PodSandbox, container *api.Container) string {
if pod != nil {
return pod.Name + "/" + container.Name
}
return container.Name
}
// Dump one or more objects, with an optional global prefix and per-object tags.
func dump(args ...interface{}) {
var (
prefix string
idx int
)
if len(args)&0x1 == 1 {
prefix = args[0].(string)
idx++
}
for ; idx < len(args)-1; idx += 2 {
tag, obj := args[idx], args[idx+1]
msg, err := yaml.Marshal(obj)
if err != nil {
log.Infof("%s: %s: failed to dump object: %v", prefix, tag, err)
continue
}
if prefix != "" {
log.Infof("%s: %s:", prefix, tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof("%s: %s", prefix, line)
}
} else {
log.Infof("%s:", tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof(" %s", line)
}
}
}
}
func main() {
var (
pluginName string
pluginIdx string
opts []stub.Option
err error
)
log = logrus.StandardLogger()
log.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
flag.StringVar(&pluginName, "name", "", "plugin name to register to NRI")
flag.StringVar(&pluginIdx, "idx", "", "plugin index to register to NRI")
flag.BoolVar(&verbose, "verbose", false, "enable (more) verbose logging")
flag.Parse()
if pluginName != "" {
opts = append(opts, stub.WithPluginName(pluginName))
}
if pluginIdx != "" {
opts = append(opts, stub.WithPluginIdx(pluginIdx))
}
p := &plugin{}
if p.stub, err = stub.New(p, opts...); err != nil {
log.Fatalf("failed to create plugin stub: %v", err)
}
err = p.stub.Run(context.Background())
if err != nil {
log.Errorf("plugin exited with error %v", err)
os.Exit(1)
}
}
nri-0.6.1/plugins/device-injector/go.mod 0000664 0000000 0000000 00000001475 14610311645 0020157 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/plugins/device-injector
go 1.18
require (
github.com/containerd/nri v0.2.0
github.com/sirupsen/logrus v1.9.0
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/containerd/ttrpc v1.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/cri-api v0.25.3 // indirect
)
replace github.com/containerd/nri => ../..
nri-0.6.1/plugins/device-injector/go.sum 0000664 0000000 0000000 00000016562 14610311645 0020207 0 ustar 00root root 0000000 0000000 github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/plugins/device-injector/sample-device-inject.yaml 0000664 0000000 0000000 00000003002 14610311645 0023711 0 ustar 00root root 0000000 0000000 #
# Once this pod is running, you can verify the results by running
# kubectl exec -c c0 bbdev0 -- ls -ls /dev/nri-null
# kubectl exec -c c1 bbdev0 -- ls -ls /dev/nri-zero
# kubectl exec -c c2 bbdev0 -- mount | grep host-home
#
apiVersion: v1
kind: Pod
metadata:
name: bbdev0
labels:
app: bbdev0
annotations:
devices.nri.io/container.c0: |+
- path: /dev/nri-null
type: c
major: 1
minor: 3
devices.nri.io/container.c1: |+
- path: /dev/nri-zero
type: c
major: 1
minor: 5
mounts.nri.io/container.c2: |+
- source: /home
destination: /host-home
type: bind
options:
- bind
- ro
spec:
containers:
- name: c0
image: busybox
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- echo bbdev0c0 $(sleep inf)
resources:
requests:
cpu: 500m
memory: '100M'
limits:
cpu: 500m
memory: '100M'
- name: c1
image: busybox
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- echo bbdev0c1 $(sleep inf)
resources:
requests:
cpu: 1
memory: '100M'
limits:
cpu: 1
memory: '100M'
- name: c2
image: busybox
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- echo bbdev0c1 $(sleep inf)
resources:
requests:
cpu: 1
memory: '100M'
limits:
cpu: 1
memory: '100M'
terminationGracePeriodSeconds: 1
nri-0.6.1/plugins/differ/ 0000775 0000000 0000000 00000000000 14610311645 0015227 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/differ/README.md 0000664 0000000 0000000 00000001415 14610311645 0016507 0 ustar 00root root 0000000 0000000 ## NRI Differ Plugin
The differ plugin can be injected before, after or between other NRI plugins
to track and show what changes these other plugins request to containers.
The plugin can register itself multiple times at multiple indices, so a single
differ instance can be used to track and show step-by-step all the changes
made to a container.
## Testing
You can test this plugin by registering it to the desired indices (for
instance `nri-differ --indices 00,20,99 --yaml`) in addition to your other
plugins that make changes to containers, then starting some containers
and examining the results. You should see container modifications printed
as yaml-diffs. Make sure you properly inject/register `differ` both at the
front of the plugin chain and after any other plugin.
nri-0.6.1/plugins/differ/go.mod 0000664 0000000 0000000 00000002427 14610311645 0016342 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/plugins/differ
go 1.18
require (
github.com/containerd/nri v0.2.0
github.com/r3labs/diff/v3 v3.0.0
github.com/sirupsen/logrus v1.9.0
github.com/sters/yaml-diff v0.4.0
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/containerd/ttrpc v1.2.3 // indirect
github.com/fatih/color v1.12.0 // indirect
github.com/goccy/go-yaml v1.8.10 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/cri-api v0.25.3 // indirect
)
replace github.com/containerd/nri => ../..
nri-0.6.1/plugins/differ/go.sum 0000664 0000000 0000000 00000300453 14610311645 0016367 0 ustar 00root root 0000000 0000000 4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo=
bitbucket.org/creachadair/shell v0.0.6/go.mod h1:8Qqi/cYk7vPnsOePHroKXDJYmb5x7ENhtiFtfZq8K+M=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.60.0/go.mod h1:yw2G51M9IfRboUH61Us8GqCeF1PzPblB823Mn2q2eAU=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/pubsub v1.5.0/go.mod h1:ZEwJccE3z93Z2HWvstpri00jOg7oO4UZDtKhwDwqF0w=
cloud.google.com/go/spanner v1.7.0/go.mod h1:sd3K2gZ9Fd0vMPLXzeCrF6fq4i63Q7aTLW/lBIfBkIk=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/sprig v2.15.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/OpenPeeDeeP/depguard v1.0.1/go.mod h1:xsIw86fROiiwelg+jB2uM9PiKihMMmUx/1V+TNhjQvM=
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE=
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQYkqmusNa815XgQio277wI47sdRh1dUOLdyC6Q=
github.com/aokoli/goutils v1.0.1/go.mod h1:SijmP0QR8LtwsmDs8Yii5Z/S4trXFGFC2oO5g9DP+DQ=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/ashanbrown/forbidigo v1.2.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI=
github.com/ashanbrown/makezero v0.0.0-20210520155254-b6261585ddde/go.mod h1:oG9Dnez7/ESBqc4EdrdNlryeo7d0KcW1ftXHm7nU/UU=
github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.36.30/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI=
github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/charithe/durationcheck v0.0.8/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg=
github.com/chavacava/garif v0.0.0-20210405164556-e8a0a408d6af/go.mod h1:Qjyv4H3//PWVzTeCezG2b9IRn6myJxJSr4TD/xo6ojU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/daixiang0/gci v0.2.8/go.mod h1:+4dZ7TISfSmqfAGv59ePaHfNzgGtIkHAhhdKggP1JAc=
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denis-tingajkin/go-header v0.4.2/go.mod h1:eLRHAVXzE5atsKAnNRDB90WHCFFnBUn4RN0nRcs1LJA=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.0.14/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/esimonov/ifshort v1.0.2/go.mod h1:yZqNJUrNn20K8Q9n2CrjTKYyVEmX209Hgu+M1LBpeZE=
github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fullstorydev/grpcurl v1.6.0/go.mod h1:ZQ+ayqbKMJNhzLmbpCiurTVlaK2M/3nqZCxaQ2Ze/sM=
github.com/fzipp/gocyclo v0.3.1/go.mod h1:DJHO6AUmbdqj2ET4Z9iArSuwWgYDRryYt2wASxc7x3E=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-critic/go-critic v0.5.6/go.mod h1:cVjj0DfqewQVIlIAGexPCaGaZDAqGE29PYDDADIVNEo=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ=
github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw=
github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI=
github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/goccy/go-yaml v1.8.10 h1:XpBOLD8cmOZlLYjUFPqSZZ+Ubi4/UKxO2eXyhg5WuAA=
github.com/goccy/go-yaml v1.8.10/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA=
github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4=
github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk=
github.com/golangci/go-misc v0.0.0-20180628070357-927a3d87b613/go.mod h1:SyvUF2NxV+sN8upjjeVYr5W7tyxaT1JVtvhKhOn2ii8=
github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU=
github.com/golangci/golangci-lint v1.41.1/go.mod h1:LPtcY3aAAU8wydHrKpnanx9Og8K/cblZSyGmI5CJZUk=
github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg=
github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o=
github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA=
github.com/golangci/revgrep v0.0.0-20210208091834-cd28932614b5/go.mod h1:LK+zW4MpyytAWQRz0M4xnzEk50lSvqDQKfx304apFkY=
github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/certificate-transparency-go v1.0.21/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
github.com/google/certificate-transparency-go v1.1.1/go.mod h1:FDKqPvSXawb2ecErVRrD+nfy23RCzyl7eqVCEmlT1Zs=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/trillian v1.3.11/go.mod h1:0tPraVHrSDkA3BO6vKX67zgLXs6SsOAbHEivX+9mPgw=
github.com/google/uuid v0.0.0-20161128191214-064e2069ce9c/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gookit/color v1.4.2/go.mod h1:fqRyamkC1W8uxl+lxCQxOT09l/vYfZ+QeiX3rKQHCoQ=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gordonklaus/ineffassign v0.0.0-20200309095847-7953dde2c7bf/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gordonklaus/ineffassign v0.0.0-20210225214923-2e10b2664254/go.mod h1:M9mZEtGIsR1oDaZagNPNG9iq9n2HrhZ17dsXk73V3Lw=
github.com/gorhill/cronexpr v0.0.0-20180427100037-88b0669f7d75/go.mod h1:g2644b03hfBX9Ov0ZBDgXXens4rxSxmqFBbhvKv2yVA=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE=
github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw=
github.com/gostaticanalysis/analysisutil v0.4.1/go.mod h1:18U/DLpRgIUd459wGxVHE0fRgmo1UgHDcbw7F5idXu0=
github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI=
github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado=
github.com/gostaticanalysis/forcetypeassert v0.0.0-20200621232751-01d4955beaa5/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak=
github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/huandu/xstrings v1.0.0/go.mod h1:4qWG/gcEcfX4z/mBDHJ++3ReCw9ibxbsNJbcucJdbSo=
github.com/huandu/xstrings v1.2.0/go.mod h1:DvyZB1rfVYsBIigL8HwpZgxHwXozlTgGqn63UyNX5k4=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4=
github.com/jingyugao/rowserrcheck v1.1.0/go.mod h1:TOQpc2SLx6huPfoFGK3UOnEG+u02D3C1GeosjupAKCA=
github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jonboulle/clockwork v0.2.0/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/juju/ratelimit v1.0.1/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julz/importas v0.0.0-20210419104244-841f0c0fe66d/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/errcheck v1.6.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.0/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kulti/thelper v0.4.0/go.mod h1:vMu2Cizjy/grP+jmsvOFDx1kYP6+PD1lqg4Yu5exl2U=
github.com/kunwardeep/paralleltest v1.0.2/go.mod h1:ZPqNm1fVHPllh5LPVujzbVz1JN2GhLxSfY+oqUsvG30=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg=
github.com/ldez/gomoddirectives v0.2.1/go.mod h1:sGicqkRgBOg//JfpXwkB9Hj0X5RyJ7mlACM5B9f6Me4=
github.com/ldez/tagliatelle v0.2.0/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88=
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/letsencrypt/pkcs11key/v4 v4.0.0/go.mod h1:EFUvBDay26dErnNb70Nd0/VW3tJiIbETBPTl9ATXQag=
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/maratori/testpackage v1.0.1/go.mod h1:ddKdw+XG0Phzhx8BFDTKgpWP4i7MpApTE5fXSKAqwDU=
github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8=
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc=
github.com/mgechev/dots v0.0.0-20190921121421-c36f7dcfbb81/go.mod h1:KQ7+USdGKfpPjXk4Ga+5XxQM4Lm4e3gAogrreFAYpOg=
github.com/mgechev/revive v1.0.7/go.mod h1:vuE5ox/4L/HDd63MCcCk3H6wTLQ6XXezRphJ8cJJOxY=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k=
github.com/mozilla/scribe v0.0.0-20180711195314-fb71baf557c1/go.mod h1:FIczTrinKo8VaLxe6PWTPEXRXDIHz2QAwiaBaP5/4a8=
github.com/mozilla/tls-observatory v0.0.0-20210209181001-cf43108d6880/go.mod h1:FUqVoUPHSEdDR0MnFM3Dh8AU0pZHLXUD127SAJGER/s=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-proto-validators v0.0.0-20180403085117-0950a7990007/go.mod h1:m2XC9Qq0AlmmVksL6FktJCdTYyLk7V3fKyp0sl1yWQo=
github.com/mwitkow/go-proto-validators v0.2.0/go.mod h1:ZfA1hW+UH/2ZHOWvQ3HnQaU0DtnpXu850MZiy+YUgcc=
github.com/nakabonne/nestif v0.3.0/go.mod h1:dI314BppzXjJ4HsCnbo7XzrJHPszZsjnk5wEBSYHI2c=
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nishanths/exhaustive v0.1.0/go.mod h1:S1j9110vxV1ECdCudXRkeMnFQ/DQk9ajLT0Uf2MYZQQ=
github.com/nishanths/predeclared v0.0.0-20190419143655-18a43bb90ffc/go.mod h1:62PewwiQTlm/7Rj+cxVYqZvDIUc+JjZq6GHAC1fsObQ=
github.com/nishanths/predeclared v0.2.1/go.mod h1:HvkGJcA3naj4lOwnFXFDkFxVtSqQMB9sbB1usJ+xjQE=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/olekukonko/tablewriter v0.0.2/go.mod h1:rSAaSIOAGT9odnlyGlUfAJaoc5w2fSBUmeGDbRWPxyQ=
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.1 h1:foqVmeWDD6yYpK+Yz3fHyNIxFYNxswxqNFjSKe+vI54=
github.com/onsi/ginkgo v1.16.1/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.11.0/go.mod h1:azGKhqFUon9Vuj0YmTfLSmx0FUwqXYSTl5re8lQLTUg=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polyfloyd/go-errorlint v0.0.0-20210510181950-ab96adb96fea/go.mod h1:wi9BfjxjF/bwiZ701TzmfKu6UKC357IOAtNr0Td0Lvw=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/pseudomuto/protoc-gen-doc v1.3.2/go.mod h1:y5+P6n3iGrbKG+9O04V5ld71in3v/bX88wUwgt+U8EA=
github.com/pseudomuto/protokit v0.2.0/go.mod h1:2PdH30hxVHsup8KpBTOXTBeMVhJZVio3Q8ViKSAXT0Q=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30=
github.com/quasilyte/go-ruleguard v0.3.4/go.mod h1:57FZgMnoo6jqxkYKmVj5Fc8vOt0rVzoE/UNAmFFIPqA=
github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/dsl v0.3.2/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU=
github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc=
github.com/quasilyte/go-ruleguard/rules v0.0.0-20210203162857-b223e0831f88/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50=
github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0=
github.com/r3labs/diff/v3 v3.0.0 h1:ZhPwNxn9gW5WLPBV9GCYaVbMdLOSmJ0DeKdCiSbOLUI=
github.com/r3labs/diff/v3 v3.0.0/go.mod h1:wCkTySAiDnZao1sZrVTDIzuzgLZ+cNPGn3LC8DlIg5g=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryancurrah/gomodguard v1.2.2/go.mod h1:tpI+C/nzvfUR3bF28b5QHpTn/jM/zlGniI++6ZlIWeE=
github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/securego/gosec/v2 v2.8.0/go.mod h1:hJZ6NT5TqoY+jmOsaxAV4cXoEdrMRLVaNPnSpUCvCZs=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs=
github.com/shirou/gopsutil/v3 v3.21.5/go.mod h1:ghfMypLDrFSWN2c9cDYFLHyynQ+QUht0cv/18ZqVczw=
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI=
github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
github.com/ssgreg/nlreturn/v2 v2.1.0/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I=
github.com/sters/yaml-diff v0.4.0 h1:nS1XbBS9AyZuMP4PFYsgQsJCBSX4HraRGI+cmH+0qH4=
github.com/sters/yaml-diff v0.4.0/go.mod h1:CWm8gBcsFr72+pN5VbBHtjmDe65ccnT+ES0GLpT3ifE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tdakkota/asciicheck v0.0.0-20200416200610-e657995f937b/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM=
github.com/tetafro/godot v1.4.7/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8=
github.com/timakin/bodyclose v0.0.0-20200424151742-cb6215831a94/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk=
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tomarrell/wrapcheck/v2 v2.1.0/go.mod h1:crK5eI4RGSUrb9duDTQ5GqcukbKZvi85vX6nbhsBAeI=
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
github.com/tommy-muehle/go-mnd/v2 v2.4.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA=
github.com/ultraware/whitespace v0.0.4/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/uudashr/gocognit v1.0.1/go.mod h1:j44Ayx2KW4+oB6SWMv8KsmHzZrOInQav7D3cQMJ5JUM=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.16.0/go.mod h1:YOKImeEosDdBPnxc0gy7INqi3m1zK6A+xl6TwOBhHCA=
github.com/valyala/quicktemplate v1.6.3/go.mod h1:fwPzK2fHuYEODzJ9pkw0ipCPNHZ2tD5KW4lOuSdPKzY=
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
github.com/viki-org/dnscache v0.0.0-20130720023526-c70c1f23c5d8/go.mod h1:dniwbG03GafCjFohMDmz6Zc6oCuiqgH6tGNyXTkHzXE=
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yeya24/promlinter v0.1.0/go.mod h1:rs5vtZzeBHqqMwXqFScncpCF6u06lezhZepno9AB1Oc=
github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg=
github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM=
github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/etcd v0.0.0-20200513171258-e048e166ab9c/go.mod h1:xCI7ZzBfRuGgBXyXO6yfWfDmlWd35khcWpUa4L0xI/k=
go.mozilla.org/mozlog v0.0.0-20170222151521-4bb13139d403/go.mod h1:jHoPAGnDrCy6kaI2tAze5Prf0Nr0w/oNkROt2lw3n3o=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/multierr v1.4.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4=
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM=
golang.org/x/crypto v0.0.0-20180501155221-613d6eafa307/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200420163511-1957bb5e6d1f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210217105451-b926d437f341/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216052735-49a3e744a425/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200422022333-3d57cf2e726e/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200626171337-aa94e735be7f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200630154851-b2d8b0336632/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200706234117-b22de6825cf7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201011145850-ed2f50202694/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201028025901-8cd080b735b3/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201114224030-61ea331ec02b/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201118003311-bd56c0adb394/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210101214203-2dba1e4ea05c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210104081019-d8d6ddbec6ee/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20181107211654-5fc9ac540362/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200626011028-ee7919e894b5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200707001353-8e8330bf89df/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.0/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.6/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4=
mvdan.cc/unparam v0.0.0-20210104141923-aac4ce9116a7/go.mod h1:hBpJkZE8H/sb+VRFvw2+rBpHNsTBcvSpk61hr8mzXZE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/plugins/differ/nri-differ.go 0000664 0000000 0000000 00000026233 14610311645 0017611 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"container/list"
"context"
"flag"
"fmt"
"os"
"strconv"
"strings"
"sync"
"github.com/r3labs/diff/v3"
"github.com/sirupsen/logrus"
"github.com/sters/yaml-diff/yamldiff"
"sigs.k8s.io/yaml"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
)
type config struct {
Indices string `json:"indices"`
LogFile string `json:"logFile"`
VerboseLevel int `json:"verboseLevel"`
Yaml bool `json:"yaml"`
}
type pluginIndex struct {
prevIndex int
nextIndex int
prevValues *list.List // Contains changedValue list from previous index
}
type changedValue struct {
podSet bool
pod api.PodSandbox
containerSet bool
container api.Container
}
type plugin struct {
stub stub.Stub
mask stub.EventMask
name string
idx int
}
var (
cfg config
log *logrus.Logger
indices map[int]pluginIndex
)
func (p *plugin) Configure(_ context.Context, nriCfg string) (stub.EventMask, error) {
log.Infof("got configuration data: %q", nriCfg)
if nriCfg == "" {
return p.mask, nil
}
oldCfg := cfg
err := yaml.Unmarshal([]byte(nriCfg), &cfg)
if err != nil {
return 0, fmt.Errorf("failed to parse provided configuration: %w", err)
}
p.mask, err = api.ParseEventMask("all")
if err != nil {
return 0, fmt.Errorf("failed to parse events in configuration: %w", err)
}
if cfg.LogFile != oldCfg.LogFile {
f, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Errorf("failed to open log file %q: %v", cfg.LogFile, err)
return 0, fmt.Errorf("failed to open log file %q: %w", cfg.LogFile, err)
}
log.SetOutput(f)
}
return p.mask, nil
}
func setValue(newValue *changedValue, pod *api.PodSandbox, container *api.Container) {
if pod != nil {
newValue.podSet = true
newValue.pod = *pod
}
if container != nil {
newValue.containerSet = true
newValue.container = *container
}
}
func (p *plugin) saveValue(pod *api.PodSandbox, container *api.Container) {
newValue := &changedValue{}
setValue(newValue, pod, container)
indices[p.idx].prevValues.PushBack(newValue)
}
func (p *plugin) differ(apifunc string, pod *api.PodSandbox, container *api.Container) {
// If we are the first plugin, then no need to diff
if indices[p.idx].prevIndex < 0 {
if cfg.VerboseLevel > 0 {
if container != nil {
p.dump(apifunc, "pod", pod, "container", container)
} else {
p.dump(apifunc, "pod", pod)
}
}
p.saveValue(pod, container)
} else {
element := indices[indices[p.idx].prevIndex].prevValues.Front()
initialValue := element.Value.(*changedValue)
indices[indices[p.idx].prevIndex].prevValues.Remove(element)
if pod != nil {
if initialValue.podSet {
podChanged := *pod
if cfg.Yaml {
p.printYamlDiff(apifunc, "pod", initialValue.pod, podChanged)
} else {
changelog, err := diff.Diff(initialValue.pod, podChanged)
if err != nil {
log.Errorf("%v", err)
return
}
p.printDiff(apifunc, &changelog, "pod", initialValue.pod, podChanged)
}
}
}
if container != nil {
if initialValue.containerSet {
containerChanged := *container
if cfg.Yaml {
p.printYamlDiff(apifunc, "container", initialValue.container, containerChanged)
} else {
changelog, err := diff.Diff(initialValue.container, containerChanged)
if err != nil {
log.Errorf("%v", err)
return
}
p.printDiff(apifunc, &changelog, "container", initialValue.container, containerChanged)
}
}
}
// Push to next index so it can diff things too
if indices[p.idx].nextIndex > 0 {
p.saveValue(pod, container)
}
}
}
func (p *plugin) Synchronize(_ context.Context, pods []*api.PodSandbox, containers []*api.Container) ([]*api.ContainerUpdate, error) {
if cfg.VerboseLevel > 2 {
p.dump("Synchronize", "pods", pods, "containers", containers)
}
return nil, nil
}
func (p *plugin) Shutdown(_ context.Context) {
p.dump("Shutdown")
}
func (p *plugin) RunPodSandbox(_ context.Context, pod *api.PodSandbox) error {
p.differ("RunPodSandbox", pod, nil)
return nil
}
func (p *plugin) StopPodSandbox(_ context.Context, pod *api.PodSandbox) error {
p.differ("StopPodSandbox", pod, nil)
return nil
}
func (p *plugin) RemovePodSandbox(_ context.Context, pod *api.PodSandbox) error {
p.differ("RemovePodSandbox", pod, nil)
return nil
}
func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
p.differ("CreateContainer", pod, container)
adjust := &api.ContainerAdjustment{}
return adjust, nil, nil
}
func (p *plugin) PostCreateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
p.differ("PostCreateContainer", pod, container)
return nil
}
func (p *plugin) StartContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
p.differ("StartContainer", pod, container)
return nil
}
func (p *plugin) PostStartContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
p.differ("PostStartContainer", pod, container)
return nil
}
func (p *plugin) UpdateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container, r *api.LinuxResources) ([]*api.ContainerUpdate, error) {
p.differ("UpdateContainer", pod, container)
return nil, nil
}
func (p *plugin) PostUpdateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
p.differ("PostUpdateContainer", pod, container)
return nil
}
func (p *plugin) StopContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) ([]*api.ContainerUpdate, error) {
p.differ("StopContainer", pod, container)
return nil, nil
}
func (p *plugin) RemoveContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
p.differ("RemoveContainer", pod, container)
return nil
}
func (p *plugin) onClose() {
log.Infof("stopped")
os.Exit(0)
}
// Dump one or more objects, with an optional global prefix and per-object tags.
func (p *plugin) dump(args ...interface{}) {
var (
prefix string
idx int
)
if len(args)&0x1 == 1 {
prefix = args[0].(string)
idx++
}
for ; idx < len(args)-1; idx += 2 {
tag, obj := args[idx], args[idx+1]
msg, err := yaml.Marshal(obj)
if err != nil {
log.Infof("%s: %s: failed to dump object: %v", prefix, tag, err)
continue
}
if prefix != "" {
log.Infof("%s %s: %s:", p.name, prefix, tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof("%s %s: %s", p.name, prefix, line)
}
} else {
log.Infof("%s %s:", p.name, tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof("%s %s", p.name, line)
}
}
}
}
func (p *plugin) printDiff(apifunc string, changelog *diff.Changelog, obj string, origValue interface{}, changedValue interface{}) {
if cfg.VerboseLevel > 1 {
log.Infof("[%d] Original values for %s", p.idx, obj)
p.dump(apifunc, obj, origValue)
}
if len(*changelog) == 0 {
log.Infof("[%d] %s: %s: %s", p.idx, apifunc, obj, "")
return
}
for _, item := range *changelog {
log.Infof("[%d] %s: %s: %s: %v: From: %v -> To: %v", p.idx, apifunc, obj, item.Type, item.Path, item.From, item.To)
}
if cfg.VerboseLevel > 1 {
log.Infof("[%d] Values after changes for %s", p.idx, obj)
p.dump(apifunc, obj, changedValue)
}
}
func (p *plugin) printYamlDiff(apifunc string, obj string, origValue interface{}, changedValue interface{}) {
msg, err := yaml.Marshal(origValue)
if err != nil {
return
}
yamlOrig := yamldiff.Load(string(msg[:]))
msg, err = yaml.Marshal(changedValue)
if err != nil {
return
}
yamlChanged := yamldiff.Load(string(msg[:]))
for _, diff := range yamldiff.Do(yamlOrig, yamlChanged) {
if diff.Status == yamldiff.DiffStatusSame {
log.Infof("[%d] %s: %s: %s", p.idx, apifunc, obj, "")
break
}
log.Infof("[%d] %s: %s: %v", p.idx, apifunc, obj, diff.Diff)
}
}
func startPlugin(wg *sync.WaitGroup, pluginName string, pluginIdx int) {
var (
opts []stub.Option
err error
)
defer wg.Done()
idxStr := fmt.Sprintf("%02d", pluginIdx)
if pluginName != "" {
opts = append(opts, stub.WithPluginName(pluginName))
}
if idxStr != "" {
opts = append(opts, stub.WithPluginIdx(idxStr))
}
p := &plugin{}
if p.mask, err = api.ParseEventMask("all"); err != nil {
log.Fatalf("Failed to parse events: %v", err)
}
p.name = fmt.Sprintf("[%s]", idxStr)
p.idx = pluginIdx
if p.stub, err = stub.New(p, append(opts, stub.WithOnClose(p.onClose))...); err != nil {
log.Fatalf("Failed to create plugin stub: %v", err)
}
err = p.stub.Run(context.Background())
if err != nil {
log.Errorf("Plugin exited with error %v", err)
os.Exit(1)
}
}
func main() {
log = logrus.StandardLogger()
log.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
flag.StringVar(&cfg.LogFile, "log-file", "", "logfile name, if logging to a file")
flag.IntVar(&cfg.VerboseLevel, "verbose-level", 0,
"Print extra information,\n"+
"level 0 (default) prints only the changes done by plugins,\n"+
"level 1 prints original data for the first invocation of this plugin,\n"+
"level 2 prints original and changed data together with the difference,\n"+
"level 3 prints all the data received (prints lot of data).")
flag.StringVar(&cfg.Indices, "indices", "0,99",
"Comma separated list of indices where to install the differ plugin to monitor the changes.\n"+
"Example: \"-indices 45,50,80\" will print the changes generated by plugins in\n"+
"indices 45, 50 and 80. Note that this plugin will install itself to index 0 and 99\n"+
"if this parameter is not given.")
flag.BoolVar(&cfg.Yaml, "yaml", false, "Print the diff in yaml")
flag.Parse()
if cfg.LogFile != "" {
f, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("failed to open log file %q: %v", cfg.LogFile, err)
}
log.SetOutput(f)
}
wg := new(sync.WaitGroup)
indexCount := strings.Count(cfg.Indices, ",")
if indexCount == 0 {
log.Fatalf("There must be at least two index given.")
return
}
indices = make(map[int]pluginIndex)
prevIndex := -1
for _, idxStr := range strings.Split(cfg.Indices, ",") {
idx, _ := strconv.Atoi(idxStr)
entry := indices[idx]
entry.prevIndex = prevIndex
entry.prevValues = list.New()
indices[idx] = entry
if prevIndex >= 0 {
if prevEntry, ok := indices[prevIndex]; ok {
prevEntry.nextIndex = idx
indices[prevIndex] = prevEntry
}
}
prevIndex = idx
wg.Add(1)
go startPlugin(wg, "Differ", idx)
}
entry := indices[prevIndex]
entry.nextIndex = -1
indices[prevIndex] = entry
wg.Wait()
}
nri-0.6.1/plugins/hook-injector/ 0000775 0000000 0000000 00000000000 14610311645 0016543 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/README.md 0000664 0000000 0000000 00000004012 14610311645 0020017 0 ustar 00root root 0000000 0000000 ## OCI Hook Injector Plugin
The [OCI runtime configuration](https://github.com/opencontainers/runtime-spec/blob/main/spec.md) supports [hooks](https://github.com/opencontainers/runtime-spec/blob/main/config.md#posix-platform-hooks), which are custom actions related to the lifecycle of a container. This plugin performs OCI hook injection into containers using the [Hook Manager](https://github.com/containers/podman/tree/8bcc086b1b9d8aa0ef3bb08d37542adf9de26ac5/pkg/hooks) package of [podman](https://github.com/containers/podman). [CRI-O](https://github.com/cri-o/cri-o) has native hook injection support using the same package. This plugin essentially achieves CRI-O compatible OCI hook injection for other runtimes using NRI.
## Testing
You can test this plugin using a Kubernetes cluster/node with a container runtime that has NRI support enabled ([Enabling NRI in Containerd](https://github.com/containerd/containerd/blob/main/docs/NRI.md#enabling-nri-support-in-containerd)). Once you've enabled NRI on your runtime, you can use the sample hook configuration, placing it at `/etc/containers/oci/hooks.d`, and the [sample hook](usr/local/sbin/demo-hook.sh), placing it at `/usr/local/sbin/`.
>*Note:* OCI hook configuration details and default file paths can be found in the [OCI Configuration Package Documentation](https://pkg.go.dev/github.com/containers/podman/v3/pkg/hooks)
Start the plugin directly on the target node by running `hook-injector -idx 10` from the folder containing the binary. Alternatively, you can create a symbolic link to the hook-injector binary in the plugin path configured for the runtime, with the idx as the prefix (ex. `10-hook-injector`)
Additional details on hook configuration can be found in the [OCI hook configuration](https://github.com/containers/podman/blob/8bcc086b1b9d8aa0ef3bb08d37542adf9de26ac5/pkg/hooks/docs/oci-hooks.5.md) documentation.
Finally, create a test pod using the [sample pod spec](sample-hook-inject.yaml) and check for the log output of the hook, which will be at `/tmp/demo-hook.log` nri-0.6.1/plugins/hook-injector/etc/ 0000775 0000000 0000000 00000000000 14610311645 0017316 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/etc/containers/ 0000775 0000000 0000000 00000000000 14610311645 0021463 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/etc/containers/oci/ 0000775 0000000 0000000 00000000000 14610311645 0022235 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/etc/containers/oci/hooks.d/ 0000775 0000000 0000000 00000000000 14610311645 0023602 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/etc/containers/oci/hooks.d/always-inject.json 0000664 0000000 0000000 00000000472 14610311645 0027252 0 ustar 00root root 0000000 0000000 {
"version": "1.0.0",
"hook": {
"path": "/usr/local/sbin/demo-hook.sh",
"args": ["this", "hook", "is", "always", "injected"],
"env": [
"DEMO_HOOK_ALWAYS_INJECTED=true"
]
},
"when": {
"always": true
},
"stages": ["prestart", "poststop"]
}
nri-0.6.1/plugins/hook-injector/etc/containers/oci/hooks.d/busybox-inject.json 0000664 0000000 0000000 00000000602 14610311645 0027440 0 ustar 00root root 0000000 0000000 {
"version": "1.0.0",
"hook": {
"path": "/usr/local/sbin/demo-hook.sh",
"args": ["this", "is", "injected", "into", "busybox"],
"env": [
"DEMO_HOOK_BUSYBOX_INJECTED=true",
"DEMO_HOOK_ARGV0=busybox"
]
},
"when": {
"commands": [
"busybox"
]
},
"stages": ["prestart", "poststop"]
}
nri-0.6.1/plugins/hook-injector/go.mod 0000664 0000000 0000000 00000001550 14610311645 0017652 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/plugins/hook-injector
go 1.18
require (
github.com/containerd/nri v0.2.0
github.com/containers/common v0.56.0
github.com/opencontainers/runtime-spec v1.1.0
github.com/sirupsen/logrus v1.9.3
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/containerd/ttrpc v1.2.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/cri-api v0.25.3 // indirect
)
replace github.com/containerd/nri => ../..
nri-0.6.1/plugins/hook-injector/go.sum 0000664 0000000 0000000 00000020110 14610311645 0017670 0 ustar 00root root 0000000 0000000 github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/containers/common v0.56.0 h1:hysHUsEai1EkMXanU26UV55wMXns/a6AYmaFqJ4fEMY=
github.com/containers/common v0.56.0/go.mod h1:IjaDdfUtcs2CfCcJMZxuut4XlvkTkY9Nlqkso9xCOq4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/pprof v0.0.0-20230323073829-e72429f035bd h1:r8yyd+DJDmsUhGrRBxH5Pj7KeFK5l+Y3FsgT8keqKtk=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI=
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/opencontainers/runtime-spec v1.1.0 h1:HHUyrt9mwHUjtasSbXSMvs4cyFxh+Bll4AjJ9odEGpg=
github.com/opencontainers/runtime-spec v1.1.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/plugins/hook-injector/hook-injector.go 0000664 0000000 0000000 00000010326 14610311645 0021647 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"github.com/containers/common/pkg/hooks"
rspec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
)
var (
log *logrus.Logger
verbose bool
)
type plugin struct {
stub stub.Stub
mgr *hooks.Manager
}
func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
ctrName := containerName(pod, container)
if verbose {
dump("CreateContainer", "pod", pod, "container", container)
}
annotations := map[string]string{}
for k, v := range container.Annotations {
annotations[k] = v
}
for k, v := range pod.Annotations {
annotations[k] = v
}
hasBindMounts := len(container.Mounts) > 0
spec := &rspec.Spec{
Process: &rspec.Process{
Args: container.Args,
},
}
if verbose {
dump(ctrName, "OCI Spec", spec)
dump(ctrName, "Annotations", annotations)
}
if _, err := p.mgr.Hooks(spec, annotations, hasBindMounts); err != nil {
log.Errorf("%s: failed to generate hooks: %v", ctrName, err)
return nil, nil, fmt.Errorf("hook generation failed: %w", err)
}
if spec.Hooks == nil {
log.Infof("%s: no hooks to inject, ignoring", ctrName)
return nil, nil, nil
}
adjust := &api.ContainerAdjustment{}
adjust.AddHooks(api.FromOCIHooks(spec.Hooks))
if verbose {
dump(ctrName, "ContainerAdjustment", adjust)
} else {
log.Infof("%s: OCI hooks injected", ctrName)
}
return adjust, nil, nil
}
// Construct a container name for log messages.
func containerName(pod *api.PodSandbox, container *api.Container) string {
if pod != nil {
return pod.Name + "/" + container.Name
}
return container.Name
}
// Dump one or more objects, with an optional global prefix and per-object tags.
func dump(args ...interface{}) {
var (
prefix string
idx int
)
if len(args)&0x1 == 1 {
prefix = args[0].(string)
idx++
}
for ; idx < len(args)-1; idx += 2 {
tag, obj := args[idx], args[idx+1]
msg, err := yaml.Marshal(obj)
if err != nil {
log.Infof("%s: %s: failed to dump object: %v", prefix, tag, err)
continue
}
if prefix != "" {
log.Infof("%s: %s:", prefix, tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof("%s: %s", prefix, line)
}
} else {
log.Infof("%s:", tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof(" %s", line)
}
}
}
}
func main() {
var (
pluginName string
pluginIdx string
opts []stub.Option
mgr *hooks.Manager
err error
)
log = logrus.StandardLogger()
log.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
flag.StringVar(&pluginName, "name", "", "plugin name to register to NRI")
flag.StringVar(&pluginIdx, "idx", "", "plugin index to register to NRI")
flag.BoolVar(&verbose, "verbose", false, "enable (more) verbose logging")
flag.Parse()
if pluginName != "" {
opts = append(opts, stub.WithPluginName(pluginName))
}
if pluginIdx != "" {
opts = append(opts, stub.WithPluginIdx(pluginIdx))
}
p := &plugin{}
if p.stub, err = stub.New(p, opts...); err != nil {
log.Errorf("failed to create plugin stub: %v", err)
os.Exit(1)
}
ctx := context.Background()
dirs := []string{hooks.DefaultDir, hooks.OverrideDir}
mgr, err = hooks.New(ctx, dirs, []string{})
if err != nil {
log.Errorf("failed to set up hook manager: %v", err)
os.Exit(1)
}
p.mgr = mgr
err = p.stub.Run(ctx)
if err != nil {
log.Errorf("plugin exited with error %v", err)
os.Exit(1)
}
}
nri-0.6.1/plugins/hook-injector/sample-hook-inject.yaml 0000664 0000000 0000000 00000001524 14610311645 0023122 0 ustar 00root root 0000000 0000000 #
# Once this pod is running, you can verify the result by running
# kubectl exec -c shell hook-demo -- env | grep DEMO_HOOK
# kubectl exec -c busybox hook-demo -- env | grep DEMO_HOOK
#
apiVersion: v1
kind: Pod
metadata:
name: hook-demo
spec:
containers:
- name: shell
image: busybox
imagePullPolicy: IfNotPresent
command:
- sh
- -c
- echo I am a shell $(sleep inf)
resources:
requests:
cpu: 100m
memory: '100M'
limits:
cpu: 100m
memory: '100M'
- name: busybox
image: busybox
imagePullPolicy: IfNotPresent
command:
- busybox
- sh
- -c
- echo busybox $(sleep inf)
resources:
requests:
cpu: 100m
memory: '100M'
limits:
cpu: 100m
memory: '100M'
terminationGracePeriodSeconds: 1
nri-0.6.1/plugins/hook-injector/usr/ 0000775 0000000 0000000 00000000000 14610311645 0017354 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/usr/local/ 0000775 0000000 0000000 00000000000 14610311645 0020446 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/usr/local/sbin/ 0000775 0000000 0000000 00000000000 14610311645 0021401 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/hook-injector/usr/local/sbin/demo-hook.sh 0000775 0000000 0000000 00000001442 14610311645 0023623 0 ustar 00root root 0000000 0000000 #!/bin/bash
# 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.
#!/bin/sh
LOG=/tmp/demo-hook.log
touch $LOG
echo "========== [pid $$] $(date) ==========" >> $LOG
echo "command: $0 $@" >> $LOG
echo "environment:" >> $LOG
env | sed 's/^/ /g' >> $LOG
nri-0.6.1/plugins/logger/ 0000775 0000000 0000000 00000000000 14610311645 0015247 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/logger/README.md 0000664 0000000 0000000 00000000637 14610311645 0016534 0 ustar 00root root 0000000 0000000 ## Sample NRI Request Logger Plugin
This plugin simply logs incoming requests and events. You can configure which
of these the plugin subscribes to. Also, if configured so this plugin can
inject an environment variable or an annotation into containers for testing
and illustrative purposes.
Note that the [differ plugin](../differ) is probably better suited for actual
debugging purposes than this simple logger.
nri-0.6.1/plugins/logger/go.mod 0000664 0000000 0000000 00000001464 14610311645 0016362 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/plugins/logger
go 1.18
require (
github.com/containerd/nri v0.2.0
github.com/sirupsen/logrus v1.9.0
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/containerd/ttrpc v1.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/cri-api v0.25.3 // indirect
)
replace github.com/containerd/nri => ../..
nri-0.6.1/plugins/logger/go.sum 0000664 0000000 0000000 00000016562 14610311645 0016414 0 ustar 00root root 0000000 0000000 github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/plugins/logger/nri-logger.go 0000664 0000000 0000000 00000016515 14610311645 0017653 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
)
type config struct {
LogFile string `json:"logFile"`
Events []string `json:"events"`
AddAnnotation string `json:"addAnnotation"`
SetAnnotation string `json:"setAnnotation"`
AddEnv string `json:"addEnv"`
SetEnv string `json:"setEnv"`
}
type plugin struct {
stub stub.Stub
mask stub.EventMask
}
var (
cfg config
log *logrus.Logger
_ = stub.ConfigureInterface(&plugin{})
)
func (p *plugin) Configure(_ context.Context, config, runtime, version string) (stub.EventMask, error) {
log.Infof("got configuration data: %q from runtime %s %s", config, runtime, version)
if config == "" {
return p.mask, nil
}
oldCfg := cfg
err := yaml.Unmarshal([]byte(config), &cfg)
if err != nil {
return 0, fmt.Errorf("failed to parse provided configuration: %w", err)
}
p.mask, err = api.ParseEventMask(cfg.Events...)
if err != nil {
return 0, fmt.Errorf("failed to parse events in configuration: %w", err)
}
if cfg.LogFile != oldCfg.LogFile {
f, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Errorf("failed to open log file %q: %v", cfg.LogFile, err)
return 0, fmt.Errorf("failed to open log file %q: %w", cfg.LogFile, err)
}
log.SetOutput(f)
}
return p.mask, nil
}
func (p *plugin) Synchronize(_ context.Context, pods []*api.PodSandbox, containers []*api.Container) ([]*api.ContainerUpdate, error) {
dump("Synchronize", "pods", pods, "containers", containers)
return nil, nil
}
func (p *plugin) Shutdown() {
dump("Shutdown")
}
func (p *plugin) RunPodSandbox(_ context.Context, pod *api.PodSandbox) error {
dump("RunPodSandbox", "pod", pod)
return nil
}
func (p *plugin) StopPodSandbox(_ context.Context, pod *api.PodSandbox) error {
dump("StopPodSandbox", "pod", pod)
return nil
}
func (p *plugin) RemovePodSandbox(_ context.Context, pod *api.PodSandbox) error {
dump("RemovePodSandbox", "pod", pod)
return nil
}
func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
dump("CreateContainer", "pod", pod, "container", container)
adjust := &api.ContainerAdjustment{}
if cfg.AddAnnotation != "" {
adjust.AddAnnotation(cfg.AddAnnotation, fmt.Sprintf("logger-pid-%d", os.Getpid()))
}
if cfg.SetAnnotation != "" {
adjust.RemoveAnnotation(cfg.SetAnnotation)
adjust.AddAnnotation(cfg.SetAnnotation, fmt.Sprintf("logger-pid-%d", os.Getpid()))
}
if cfg.AddEnv != "" {
adjust.AddEnv(cfg.AddEnv, fmt.Sprintf("logger-pid-%d", os.Getpid()))
}
if cfg.SetEnv != "" {
adjust.RemoveEnv(cfg.SetEnv)
adjust.AddEnv(cfg.SetEnv, fmt.Sprintf("logger-pid-%d", os.Getpid()))
}
return adjust, nil, nil
}
func (p *plugin) PostCreateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
dump("PostCreateContainer", "pod", pod, "container", container)
return nil
}
func (p *plugin) StartContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
dump("StartContainer", "pod", pod, "container", container)
return nil
}
func (p *plugin) PostStartContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
dump("PostStartContainer", "pod", pod, "container", container)
return nil
}
func (p *plugin) UpdateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container, r *api.LinuxResources) ([]*api.ContainerUpdate, error) {
dump("UpdateContainer", "pod", pod, "container", container, "resources", r)
return nil, nil
}
func (p *plugin) PostUpdateContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
dump("PostUpdateContainer", "pod", pod, "container", container)
return nil
}
func (p *plugin) StopContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) ([]*api.ContainerUpdate, error) {
dump("StopContainer", "pod", pod, "container", container)
return nil, nil
}
func (p *plugin) RemoveContainer(_ context.Context, pod *api.PodSandbox, container *api.Container) error {
dump("RemoveContainer", "pod", pod, "container", container)
return nil
}
func (p *plugin) onClose() {
os.Exit(0)
}
// Dump one or more objects, with an optional global prefix and per-object tags.
func dump(args ...interface{}) {
var (
prefix string
idx int
)
if len(args)&0x1 == 1 {
prefix = args[0].(string)
idx++
}
for ; idx < len(args)-1; idx += 2 {
tag, obj := args[idx], args[idx+1]
msg, err := yaml.Marshal(obj)
if err != nil {
log.Infof("%s: %s: failed to dump object: %v", prefix, tag, err)
continue
}
if prefix != "" {
log.Infof("%s: %s:", prefix, tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof("%s: %s", prefix, line)
}
} else {
log.Infof("%s:", tag)
for _, line := range strings.Split(strings.TrimSpace(string(msg)), "\n") {
log.Infof(" %s", line)
}
}
}
}
func main() {
var (
pluginName string
pluginIdx string
events string
opts []stub.Option
err error
)
log = logrus.StandardLogger()
log.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
flag.StringVar(&pluginName, "name", "", "plugin name to register to NRI")
flag.StringVar(&pluginIdx, "idx", "", "plugin index to register to NRI")
flag.StringVar(&events, "events", "all", "comma-separated list of events to subscribe for")
flag.StringVar(&cfg.LogFile, "log-file", "", "logfile name, if logging to a file")
flag.StringVar(&cfg.AddAnnotation, "add-annotation", "", "add this annotation to containers")
flag.StringVar(&cfg.SetAnnotation, "set-annotation", "", "set this annotation on containers")
flag.StringVar(&cfg.AddEnv, "add-env", "", "add this environment variable for containers")
flag.StringVar(&cfg.SetEnv, "set-env", "", "set this environment variable for containers")
flag.Parse()
if cfg.LogFile != "" {
f, err := os.OpenFile(cfg.LogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("failed to open log file %q: %v", cfg.LogFile, err)
}
log.SetOutput(f)
}
if pluginName != "" {
opts = append(opts, stub.WithPluginName(pluginName))
}
if pluginIdx != "" {
opts = append(opts, stub.WithPluginIdx(pluginIdx))
}
p := &plugin{}
if p.mask, err = api.ParseEventMask(events); err != nil {
log.Fatalf("failed to parse events: %v", err)
}
cfg.Events = strings.Split(events, ",")
if p.stub, err = stub.New(p, append(opts, stub.WithOnClose(p.onClose))...); err != nil {
log.Fatalf("failed to create plugin stub: %v", err)
}
err = p.stub.Run(context.Background())
if err != nil {
log.Errorf("plugin exited with error %v", err)
os.Exit(1)
}
}
nri-0.6.1/plugins/template/ 0000775 0000000 0000000 00000000000 14610311645 0015603 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/template/go.mod 0000664 0000000 0000000 00000001466 14610311645 0016720 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/plugins/template
go 1.18
require (
github.com/containerd/nri v0.2.0
github.com/sirupsen/logrus v1.9.0
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/containerd/ttrpc v1.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
k8s.io/cri-api v0.25.3 // indirect
)
replace github.com/containerd/nri => ../..
nri-0.6.1/plugins/template/go.sum 0000664 0000000 0000000 00000016562 14610311645 0016750 0 ustar 00root root 0000000 0000000 github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/plugins/template/plugin.go 0000664 0000000 0000000 00000014043 14610311645 0017432 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"flag"
"fmt"
"os"
"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
)
type config struct {
CfgParam1 string `json:"cfgParam1"`
}
type plugin struct {
stub stub.Stub
mask stub.EventMask
}
var (
cfg config
log *logrus.Logger
)
func (p *plugin) Configure(_ context.Context, config, runtime, version string) (stub.EventMask, error) {
log.Infof("Connected to %s/%s...", runtime, version)
if config == "" {
return 0, nil
}
err := yaml.Unmarshal([]byte(config), &cfg)
if err != nil {
return 0, fmt.Errorf("failed to parse configuration: %w", err)
}
log.Info("Got configuration data %+v...", cfg)
return 0, nil
}
func (p *plugin) Synchronize(_ context.Context, pods []*api.PodSandbox, containers []*api.Container) ([]*api.ContainerUpdate, error) {
log.Info("Synchronizing state with the runtime...")
return nil, nil
}
func (p *plugin) Shutdown(_ context.Context) {
log.Info("Runtime shutting down...")
}
func (p *plugin) RunPodSandbox(_ context.Context, pod *api.PodSandbox) error {
log.Infof("Started pod %s/%s...", pod.GetNamespace(), pod.GetName())
return nil
}
func (p *plugin) StopPodSandbox(_ context.Context, pod *api.PodSandbox) error {
log.Infof("Stopped pod %s/%s...", pod.GetNamespace(), pod.GetName())
return nil
}
func (p *plugin) RemovePodSandbox(_ context.Context, pod *api.PodSandbox) error {
log.Infof("Removed pod %s/%s...", pod.GetNamespace(), pod.GetName())
return nil
}
func (p *plugin) CreateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
log.Infof("Creating container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
//
// This is the container creation request handler. Because the container
// has not been created yet, this is the lifecycle event which allows you
// the largest set of changes to the container's configuration, including
// some of the later immautable parameters. Take a look at the adjustment
// functions in pkg/api/adjustment.go to see the available controls.
//
// In addition to reconfiguring the container being created, you are also
// allowed to update other existing containers. Take a look at the update
// functions in pkg/api/update.go to see the available controls.
//
adjustment := &api.ContainerAdjustment{}
updates := []*api.ContainerUpdate{}
return adjustment, updates, nil
}
func (p *plugin) PostCreateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
log.Infof("Created container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *plugin) StartContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
log.Infof("Starting container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *plugin) PostStartContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
log.Infof("Started container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *plugin) UpdateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container, r *api.LinuxResources) ([]*api.ContainerUpdate, error) {
log.Infof("Updating container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
//
// This is the container update request handler. You can make changes to
// the container update before it is applied. Take a look at the functions
// in pkg/api/update.go to see the available controls.
//
// In addition to altering the pending update itself, you are also allowed
// to update other existing containers.
//
updates := []*api.ContainerUpdate{}
return updates, nil
}
func (p *plugin) PostUpdateContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
log.Infof("Updated container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *plugin) StopContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
log.Infof("Stopped container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
//
// This is the container (post-)stop request handler. You can update any
// of the remaining running containers. Take a look at the functions in
// pkg/api/update.go to see the available controls.
//
return []*api.ContainerUpdate{}, nil
}
func (p *plugin) RemoveContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
log.Infof("Removed container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
return nil
}
func (p *plugin) onClose() {
log.Infof("Connection to the runtime lost, exiting...")
os.Exit(0)
}
func main() {
var (
pluginName string
pluginIdx string
err error
)
log = logrus.StandardLogger()
log.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
flag.StringVar(&pluginName, "name", "", "plugin name to register to NRI")
flag.StringVar(&pluginIdx, "idx", "", "plugin index to register to NRI")
flag.Parse()
p := &plugin{}
opts := []stub.Option{
stub.WithOnClose(p.onClose),
}
if pluginName != "" {
opts = append(opts, stub.WithPluginName(pluginName))
}
if pluginIdx != "" {
opts = append(opts, stub.WithPluginIdx(pluginIdx))
}
if p.stub, err = stub.New(p, opts...); err != nil {
log.Fatalf("failed to create plugin stub: %v", err)
}
if err = p.stub.Run(context.Background()); err != nil {
log.Errorf("plugin exited (%v)", err)
os.Exit(1)
}
}
nri-0.6.1/plugins/ulimit-adjuster/ 0000775 0000000 0000000 00000000000 14610311645 0017112 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/ulimit-adjuster/README.md 0000664 0000000 0000000 00000002234 14610311645 0020372 0 ustar 00root root 0000000 0000000 ## ulimit Adjuster Plugin
This sample plugin can adjust ulimits for containers using pod annotations.
### Annotations
ulimits are annotated using the key
`ulimits.nri.containerd.io/container.$CONTAINER_NAME`, which adjusts ulimits
for `$CONTAINER_NAME`. The ulimit names are the valid names of Linux resource
limits, which can be seen on the
[`setrlimit(2)` manual page](https://linux.die.net/man/2/setrlimit).
The annotation syntax for ulimit adjustment is
```
- type: RLIMIT_NOFILE
soft: 1024
hard: 4096
- path: RLIMIT_MEMLOCK
soft: 1073741824
hard: 1073741824
...
```
All fields are mandatory (`soft` and `hard` will be interpreted as 0 if
missing). The `type` field accepts names in uppercase letters
("RLIMIT_NOFILE"), lowercase letters ("rlimit_memlock"), and omitting the
"RLIMIT_" prefix ("nproc").
## Testing
You can test this plugin using a kubernetes cluster/node with a container
runtime that has NRI support enabled. Start the plugin on the target node
(`ulimit-adjuster -idx 10`), create a pod with some annotated ulimits, then
verify that those get adjusted in the container. See the
[sample pod spec](sample-ulimit-adjust.yaml) for an example. nri-0.6.1/plugins/ulimit-adjuster/adjuster.go 0000664 0000000 0000000 00000010740 14610311645 0021264 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"flag"
"fmt"
"os"
"strings"
"github.com/containerd/log"
"github.com/sirupsen/logrus"
"sigs.k8s.io/yaml"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
)
const (
ulimitKey = "ulimits.nri.containerd.io"
rlimitPrefix = "RLIMIT_"
)
var (
valid = map[string]struct{}{
"AS": {},
"CORE": {},
"CPU": {},
"DATA": {},
"FSIZE": {},
"LOCKS": {},
"MEMLOCK": {},
"MSGQUEUE": {},
"NICE": {},
"NOFILE": {},
"NPROC": {},
"RSS": {},
"RTPRIO": {},
"RTTIME": {},
"SIGPENDING": {},
"STACK": {},
}
)
func main() {
var (
pluginName string
pluginIdx string
verbose bool
opts []stub.Option
)
l := logrus.StandardLogger()
l.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
flag.StringVar(&pluginName, "name", "", "plugin name to register to NRI")
flag.StringVar(&pluginIdx, "idx", "", "plugin index to register to NRI")
flag.BoolVar(&verbose, "verbose", false, "enable (more) verbose logging")
flag.Parse()
ctx := log.WithLogger(context.Background(), l.WithField("name", pluginName).WithField("idx", pluginIdx))
log.G(ctx).WithField("verbose", verbose).Info("starting plugin")
if verbose {
l.SetLevel(logrus.DebugLevel)
}
if pluginName != "" {
opts = append(opts, stub.WithPluginName(pluginName))
}
if pluginIdx != "" {
opts = append(opts, stub.WithPluginIdx(pluginIdx))
}
p := &plugin{l: log.G(ctx)}
var err error
if p.stub, err = stub.New(p, opts...); err != nil {
log.G(ctx).Fatalf("failed to create plugin stub: %v", err)
}
if err := p.stub.Run(context.Background()); err != nil {
log.G(ctx).Errorf("plugin exited with error %v", err)
os.Exit(1)
}
}
type plugin struct {
stub stub.Stub
l *logrus.Entry
}
func (p *plugin) CreateContainer(
ctx context.Context,
pod *api.PodSandbox,
container *api.Container) (*api.ContainerAdjustment, []*api.ContainerUpdate, error) {
if pod != nil {
p.l = p.l.WithField("pod", pod.Name)
}
if container != nil {
p.l = p.l.WithField("container", container.Name)
}
ctx = log.WithLogger(ctx, p.l)
log.G(ctx).Debug("create container")
ulimits, err := parseUlimits(ctx, container.Name, pod.Annotations)
if err != nil {
log.G(ctx).WithError(err).Debug("failed to parse annotations")
return nil, nil, err
}
adjust, err := adjustUlimits(ctx, ulimits)
if err != nil {
return nil, nil, err
}
return adjust, nil, nil
}
type ulimit struct {
Type string `json:"type"`
Hard uint64 `json:"hard"`
Soft uint64 `json:"soft"`
}
func parseUlimits(ctx context.Context, container string, annotations map[string]string) ([]ulimit, error) {
key := ulimitKey + "/container." + container
val, ok := annotations[key]
if !ok {
log.G(ctx).Debugf("no annotations found with key %q", key)
return nil, nil
}
ulimits := make([]ulimit, 0)
if err := yaml.Unmarshal([]byte(val), &ulimits); err != nil {
return nil, err
}
for i := range ulimits {
u := ulimits[i]
typ := strings.TrimPrefix(strings.ToUpper(u.Type), rlimitPrefix)
if _, ok := valid[typ]; !ok {
log.G(ctx).WithField("raw", u.Type).WithField("trimmed", typ).Debug("failed to parse type")
return nil, fmt.Errorf("failed to parse type: %q", u.Type)
}
ulimits[i].Type = rlimitPrefix + typ
}
return ulimits, nil
}
func adjustUlimits(ctx context.Context, ulimits []ulimit) (*api.ContainerAdjustment, error) {
adjust := &api.ContainerAdjustment{}
for _, u := range ulimits {
l := log.G(ctx).WithField("type", u.Type).WithField("hard", u.Hard).WithField("soft", u.Soft)
if u.Hard < u.Soft {
l.Debug("failed to apply ulimit with hard < soft")
return nil, fmt.Errorf("ulimit %q must have hard limit >= soft limit", u.Type)
}
log.G(ctx).WithField("type", u.Type).WithField("hard", u.Hard).WithField("soft", u.Soft).Debug("adjust rlimit")
adjust.AddRlimit(u.Type, u.Hard, u.Soft)
}
return adjust, nil
}
nri-0.6.1/plugins/ulimit-adjuster/adjuster_test.go 0000664 0000000 0000000 00000012007 14610311645 0022321 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"github.com/containerd/nri/pkg/api"
)
func TestParseAnnotations(t *testing.T) {
tests := map[string]struct {
container string
annotations map[string]string
expected []ulimit
errStr string
}{
"no-annotations": {
container: "foo",
},
"unrelated-annotation": {
container: "foo",
annotations: map[string]string{"bar": "baz"},
},
"one-valid": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: RLIMIT_NOFILE
soft: 123
hard: 456
`},
expected: []ulimit{{
Type: "RLIMIT_NOFILE",
Hard: 456,
Soft: 123,
}},
},
"multiple-valid": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: RLIMIT_NOFILE
soft: 123
hard: 456
- type: RLIMIT_NPROC
soft: 456
hard: 789
`},
expected: []ulimit{{
Type: "RLIMIT_NOFILE",
Hard: 456,
Soft: 123,
}, {
Type: "RLIMIT_NPROC",
Hard: 789,
Soft: 456,
}},
},
"missing-prefix": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: AS
soft: 123
hard: 456
`},
expected: []ulimit{{
Type: "RLIMIT_AS",
Hard: 456,
Soft: 123,
}},
},
"lower-case": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: rlimit_core
soft: 123
hard: 456
`},
expected: []ulimit{{
Type: "RLIMIT_CORE",
Hard: 456,
Soft: 123,
}},
},
"lower-case-missing-prefix": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: cpu
soft: 123
hard: 456
`},
expected: []ulimit{{
Type: "RLIMIT_CPU",
Hard: 456,
Soft: 123,
}},
},
"invalid-prefix": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: ULIMIT_NOFILE
soft: 123
hard: 456
`},
errStr: `failed to parse type: "ULIMIT_NOFILE"`,
},
"invalid-rlimit": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: RLIMIT_FOO
soft: 123
hard: 456
`},
errStr: `failed to parse type: "RLIMIT_FOO"`,
},
"one-invalid": {
container: "foo",
annotations: map[string]string{
"ulimits.nri.containerd.io/container.foo": `
- type: RLIMIT_NICE
soft: 456
hard: 789
- type: RLIMIT_BAR
soft: 123
hard: 456
`},
errStr: `failed to parse type: "RLIMIT_BAR"`,
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
ulimits, err := parseUlimits(context.Background(), tc.container, tc.annotations)
if tc.errStr != "" {
assert.EqualError(t, err, tc.errStr)
assert.Nil(t, ulimits)
} else {
assert.NoError(t, err)
assert.EqualValues(t, tc.expected, ulimits)
}
})
}
}
func TestAdjustUlimits(t *testing.T) {
tests := map[string]struct {
ulimits []ulimit
expected *api.ContainerAdjustment
errStr string
}{
"empty": {
ulimits: nil,
expected: &api.ContainerAdjustment{},
},
"invalid-hard": {
ulimits: []ulimit{{
Type: "RLIMIT_NOFILE",
Hard: 0,
Soft: 100,
}},
errStr: `ulimit "RLIMIT_NOFILE" must have hard limit >= soft limit`,
},
"one": {
ulimits: []ulimit{{
Type: "RLIMIT_MEMLOCK",
Hard: 100,
Soft: 99,
}},
expected: &api.ContainerAdjustment{Rlimits: []*api.POSIXRlimit{{
Type: "RLIMIT_MEMLOCK",
Hard: 100,
Soft: 99,
}}},
},
"one-invalid": {
ulimits: []ulimit{{
Type: "RLIMIT_MEMLOCK",
Hard: 100,
Soft: 99,
}, {
Type: "RLIMIT_NOFILE",
Hard: 0,
Soft: 100,
}},
errStr: `ulimit "RLIMIT_NOFILE" must have hard limit >= soft limit`,
},
"multiple-valid": {
ulimits: []ulimit{{
Type: "RLIMIT_MEMLOCK",
Hard: 100,
Soft: 99,
}, {
Type: "RLIMIT_AS",
Hard: 10,
Soft: 0,
}},
expected: &api.ContainerAdjustment{Rlimits: []*api.POSIXRlimit{{
Type: "RLIMIT_MEMLOCK",
Hard: 100,
Soft: 99,
}, {
Type: "RLIMIT_AS",
Hard: 10,
Soft: 0,
}}},
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
adjust, err := adjustUlimits(context.Background(), tc.ulimits)
if tc.errStr != "" {
assert.EqualError(t, err, tc.errStr)
assert.Nil(t, adjust)
} else {
assert.NoError(t, err)
assert.Equal(t, tc.expected, adjust)
}
})
}
}
nri-0.6.1/plugins/ulimit-adjuster/go.mod 0000664 0000000 0000000 00000002045 14610311645 0020221 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/plugins/ulimit-adjuster
go 1.19
replace github.com/containerd/nri => ../..
require (
github.com/containerd/log v0.1.0
github.com/containerd/nri v0.0.0-00010101000000-000000000000
github.com/sirupsen/logrus v1.9.3
github.com/stretchr/testify v1.8.2
sigs.k8s.io/yaml v1.3.0
)
require (
github.com/containerd/ttrpc v1.2.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/cri-api v0.25.3 // indirect
)
nri-0.6.1/plugins/ulimit-adjuster/go.sum 0000664 0000000 0000000 00000020046 14610311645 0020247 0 ustar 00root root 0000000 0000000 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.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
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.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/plugins/ulimit-adjuster/sample-ulimit-adjust.yaml 0000664 0000000 0000000 00000000711 14610311645 0024047 0 ustar 00root root 0000000 0000000 apiVersion: v1
kind: Pod
metadata:
name: sleep
annotations:
ulimits.nri.containerd.io/container.sleep: |
- type: memlock
hard: 987654
soft: 645321
- type: RLIMIT_NOFILE
hard: 4096
soft: 1024
- type: nproc
hard: 9000
spec:
containers:
- name: sleep
image: ubuntu:latest
command:
- /bin/bash
- -c
- "ulimit -a; ulimit -Ha; sleep inf"
terminationGracePeriodSeconds: 3
nri-0.6.1/plugins/v010-adapter/ 0000775 0000000 0000000 00000000000 14610311645 0016074 5 ustar 00root root 0000000 0000000 nri-0.6.1/plugins/v010-adapter/README.md 0000664 0000000 0000000 00000003154 14610311645 0017356 0 ustar 00root root 0000000 0000000 ## NRI v0.1.0 Compatibility Plugin
This plugin aims to emulate the original NRI API and functionality. It uses
the v0.1.0 NRI Client package to load any v0.1.0 plugins and hook them into
the start and stop lifecycle events of pods and containers. The data passed
to the v0.1.0 plugins is reconstructed from the NRI event data this plugin
receives. It is not guaranteed to be 100% identical to the data provided by
the original interface but believed to be close enough to allow old plugins
to function.
## Testing
You can enable backward compatibility by compiling this plugin, installing,
then linking it among the automatically launched plugins.
```
# Compile v0.1.0 adapter plugin and install it.
make $(pwd)/build/bin/v010-adapter
sudo cp build/bin/v010-adapter /usr/local/bin
# Make sure NRI is enabled in containerd:
systemctl stop containerd
cp /etc/containerd/config.toml /etc/containerd/config.toml.orig
containerd config dump > /etc/containerd/config.toml
$EDITOR /etc/containerd/config.toml
# Change `disable = true` to `disable = false` in the
# `[plugins."io.containerd.nri.v1.nri"]` section.
systemctl start containerd
# Verify that NRI is enabled.
[ -e /var/run/nri.sock ] && echo "NRI is enabled" || echo "NRI is disabled"
# Link the adapter plugin among the automatically launched plugins.
sudo mkdir -p /opt/nri/plugins
sudo ln -s /usr/local/bin/v010-adapter /opt/nri/plugins/00-v010-adapter
```
Once this is done, any NRI v0.1.0 plugin binaries found in `/opt/nri/bin`
which are also enabled in /etc/nri/conf.json should be executed for each
RunPodSandbox, StopPodSandbox, StartContainer and StopContainer events.
nri-0.6.1/plugins/v010-adapter/go.mod 0000664 0000000 0000000 00000003545 14610311645 0017211 0 ustar 00root root 0000000 0000000 module github.com/containerd/nri/plugins/v010-adapter
go 1.18
require (
github.com/containerd/containerd v1.6.9
github.com/containerd/nri v0.2.0
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb
github.com/sirupsen/logrus v1.9.0
)
require (
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Microsoft/hcsshim v0.9.4 // indirect
github.com/containerd/cgroups v1.0.3 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/containerd/fifo v1.0.0 // indirect
github.com/containerd/ttrpc v1.2.3 // indirect
github.com/containerd/typeurl v1.0.2 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/gogo/googleapis v1.4.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/klauspost/compress v1.15.9 // indirect
github.com/moby/locker v1.0.1 // indirect
github.com/moby/sys/mountinfo v0.6.2 // indirect
github.com/moby/sys/signal v0.6.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/opencontainers/runc v1.1.2 // indirect
github.com/opencontainers/selinux v1.10.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
go.opencensus.io v0.24.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sync v0.2.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d // indirect
google.golang.org/grpc v1.57.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
k8s.io/cri-api v0.25.3 // indirect
)
replace github.com/containerd/nri => ../..
nri-0.6.1/plugins/v010-adapter/go.sum 0000664 0000000 0000000 00000724045 14610311645 0017243 0 ustar 00root root 0000000 0000000 bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=
cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=
cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=
cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY=
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM=
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY=
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ=
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U=
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A=
cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc=
cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU=
cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA=
cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFOKM=
cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
cloud.google.com/go v0.110.2/go.mod h1:k04UEeEtb6ZBRTv3dZz4CeJC3jKGxyhl0sAiVVquxiw=
cloud.google.com/go v0.110.4/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
cloud.google.com/go/accessapproval v1.7.1/go.mod h1:JYczztsHRMK7NTXb6Xw+dwbs/WnOJxbo/2mTI+Kgg68=
cloud.google.com/go/accesscontextmanager v1.3.0/go.mod h1:TgCBehyr5gNMz7ZaH9xubp+CE8dkrszb4oK9CWyvD4o=
cloud.google.com/go/accesscontextmanager v1.4.0/go.mod h1:/Kjh7BBu/Gh83sv+K60vN9QE5NJcd80sU33vIe2IFPE=
cloud.google.com/go/accesscontextmanager v1.6.0/go.mod h1:8XCvZWfYw3K/ji0iVnp+6pu7huxoQTLmxAbVjbloTtM=
cloud.google.com/go/accesscontextmanager v1.7.0/go.mod h1:CEGLewx8dwa33aDAZQujl7Dx+uYhS0eay198wB/VumQ=
cloud.google.com/go/accesscontextmanager v1.8.0/go.mod h1:uI+AI/r1oyWK99NN8cQ3UK76AMelMzgZCvJfsi2c+ps=
cloud.google.com/go/accesscontextmanager v1.8.1/go.mod h1:JFJHfvuaTC+++1iL1coPiG1eu5D24db2wXCDWDjIrxo=
cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw=
cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY=
cloud.google.com/go/aiplatform v1.27.0/go.mod h1:Bvxqtl40l0WImSb04d0hXFU7gDOiq9jQmorivIiWcKg=
cloud.google.com/go/aiplatform v1.35.0/go.mod h1:7MFT/vCaOyZT/4IIFfxH4ErVg/4ku6lKv3w0+tFTgXQ=
cloud.google.com/go/aiplatform v1.36.1/go.mod h1:WTm12vJRPARNvJ+v6P52RDHCNe4AhvjcIZ/9/RRHy/k=
cloud.google.com/go/aiplatform v1.37.0/go.mod h1:IU2Cv29Lv9oCn/9LkFiiuKfwrRTq+QQMbW+hPCxJGZw=
cloud.google.com/go/aiplatform v1.45.0/go.mod h1:Iu2Q7sC7QGhXUeOhAj/oCK9a+ULz1O4AotZiqjQ8MYA=
cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI=
cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4=
cloud.google.com/go/analytics v0.17.0/go.mod h1:WXFa3WSym4IZ+JiKmavYdJwGG/CvpqiqczmL59bTD9M=
cloud.google.com/go/analytics v0.18.0/go.mod h1:ZkeHGQlcIPkw0R/GW+boWHhCOR43xz9RN/jn7WcqfIE=
cloud.google.com/go/analytics v0.19.0/go.mod h1:k8liqf5/HCnOUkbawNtrWWc+UAzyDlW89doe8TtoDsE=
cloud.google.com/go/analytics v0.21.2/go.mod h1:U8dcUtmDmjrmUTnnnRnI4m6zKn/yaA5N9RlEkYFHpQo=
cloud.google.com/go/apigateway v1.3.0/go.mod h1:89Z8Bhpmxu6AmUxuVRg/ECRGReEdiP3vQtk4Z1J9rJk=
cloud.google.com/go/apigateway v1.4.0/go.mod h1:pHVY9MKGaH9PQ3pJ4YLzoj6U5FUDeDFBllIz7WmzJoc=
cloud.google.com/go/apigateway v1.5.0/go.mod h1:GpnZR3Q4rR7LVu5951qfXPJCHquZt02jf7xQx7kpqN8=
cloud.google.com/go/apigateway v1.6.1/go.mod h1:ufAS3wpbRjqfZrzpvLC2oh0MFlpRJm2E/ts25yyqmXA=
cloud.google.com/go/apigeeconnect v1.3.0/go.mod h1:G/AwXFAKo0gIXkPTVfZDd2qA1TxBXJ3MgMRBQkIi9jc=
cloud.google.com/go/apigeeconnect v1.4.0/go.mod h1:kV4NwOKqjvt2JYR0AoIWo2QGfoRtn/pkS3QlHp0Ni04=
cloud.google.com/go/apigeeconnect v1.5.0/go.mod h1:KFaCqvBRU6idyhSNyn3vlHXc8VMDJdRmwDF6JyFRqZ8=
cloud.google.com/go/apigeeconnect v1.6.1/go.mod h1:C4awq7x0JpLtrlQCr8AzVIzAaYgngRqWf9S5Uhg+wWs=
cloud.google.com/go/apigeeregistry v0.4.0/go.mod h1:EUG4PGcsZvxOXAdyEghIdXwAEi/4MEaoqLMLDMIwKXY=
cloud.google.com/go/apigeeregistry v0.5.0/go.mod h1:YR5+s0BVNZfVOUkMa5pAR2xGd0A473vA5M7j247o1wM=
cloud.google.com/go/apigeeregistry v0.6.0/go.mod h1:BFNzW7yQVLZ3yj0TKcwzb8n25CFBri51GVGOEUcgQsc=
cloud.google.com/go/apigeeregistry v0.7.1/go.mod h1:1XgyjZye4Mqtw7T9TsY4NW10U7BojBvG4RMD+vRDrIw=
cloud.google.com/go/apikeys v0.4.0/go.mod h1:XATS/yqZbaBK0HOssf+ALHp8jAlNHUgyfprvNcBIszU=
cloud.google.com/go/apikeys v0.5.0/go.mod h1:5aQfwY4D+ewMMWScd3hm2en3hCj+BROlyrt3ytS7KLI=
cloud.google.com/go/apikeys v0.6.0/go.mod h1:kbpXu5upyiAlGkKrJgQl8A0rKNNJ7dQ377pdroRSSi8=
cloud.google.com/go/appengine v1.4.0/go.mod h1:CS2NhuBuDXM9f+qscZ6V86m1MIIqPj3WC/UoEuR1Sno=
cloud.google.com/go/appengine v1.5.0/go.mod h1:TfasSozdkFI0zeoxW3PTBLiNqRmzraodCWatWI9Dmak=
cloud.google.com/go/appengine v1.6.0/go.mod h1:hg6i0J/BD2cKmDJbaFSYHFyZkgBEfQrDg/X0V5fJn84=
cloud.google.com/go/appengine v1.7.0/go.mod h1:eZqpbHFCqRGa2aCdope7eC0SWLV1j0neb/QnMJVWx6A=
cloud.google.com/go/appengine v1.7.1/go.mod h1:IHLToyb/3fKutRysUlFO0BPt5j7RiQ45nrzEJmKTo6E=
cloud.google.com/go/appengine v1.8.1/go.mod h1:6NJXGLVhZCN9aQ/AEDvmfzKEfoYBlfB80/BHiKVputY=
cloud.google.com/go/area120 v0.5.0/go.mod h1:DE/n4mp+iqVyvxHN41Vf1CR602GiHQjFPusMFW6bGR4=
cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0=
cloud.google.com/go/area120 v0.7.0/go.mod h1:a3+8EUD1SX5RUcCs3MY5YasiO1z6yLiNLRiFrykbynY=
cloud.google.com/go/area120 v0.7.1/go.mod h1:j84i4E1RboTWjKtZVWXPqvK5VHQFJRF2c1Nm69pWm9k=
cloud.google.com/go/area120 v0.8.1/go.mod h1:BVfZpGpB7KFVNxPiQBuHkX6Ed0rS51xIgmGyjrAfzsg=
cloud.google.com/go/artifactregistry v1.6.0/go.mod h1:IYt0oBPSAGYj/kprzsBjZ/4LnG/zOcHyFHjWPCi6SAQ=
cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk=
cloud.google.com/go/artifactregistry v1.8.0/go.mod h1:w3GQXkJX8hiKN0v+at4b0qotwijQbYUqF2GWkZzAhC0=
cloud.google.com/go/artifactregistry v1.9.0/go.mod h1:2K2RqvA2CYvAeARHRkLDhMDJ3OXy26h3XW+3/Jh2uYc=
cloud.google.com/go/artifactregistry v1.11.1/go.mod h1:lLYghw+Itq9SONbCa1YWBoWs1nOucMH0pwXN1rOBZFI=
cloud.google.com/go/artifactregistry v1.11.2/go.mod h1:nLZns771ZGAwVLzTX/7Al6R9ehma4WUEhZGWV6CeQNQ=
cloud.google.com/go/artifactregistry v1.12.0/go.mod h1:o6P3MIvtzTOnmvGagO9v/rOjjA0HmhJ+/6KAXrmYDCI=
cloud.google.com/go/artifactregistry v1.13.0/go.mod h1:uy/LNfoOIivepGhooAUpL1i30Hgee3Cu0l4VTWHUC08=
cloud.google.com/go/artifactregistry v1.14.1/go.mod h1:nxVdG19jTaSTu7yA7+VbWL346r3rIdkZ142BSQqhn5E=
cloud.google.com/go/asset v1.5.0/go.mod h1:5mfs8UvcM5wHhqtSv8J1CtxxaQq3AdBxxQi2jGW/K4o=
cloud.google.com/go/asset v1.7.0/go.mod h1:YbENsRK4+xTiL+Ofoj5Ckf+O17kJtgp3Y3nn4uzZz5s=
cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0=
cloud.google.com/go/asset v1.9.0/go.mod h1:83MOE6jEJBMqFKadM9NLRcs80Gdw76qGuHn8m3h8oHQ=
cloud.google.com/go/asset v1.10.0/go.mod h1:pLz7uokL80qKhzKr4xXGvBQXnzHn5evJAEAtZiIb0wY=
cloud.google.com/go/asset v1.11.1/go.mod h1:fSwLhbRvC9p9CXQHJ3BgFeQNM4c9x10lqlrdEUYXlJo=
cloud.google.com/go/asset v1.12.0/go.mod h1:h9/sFOa4eDIyKmH6QMpm4eUK3pDojWnUhTgJlk762Hg=
cloud.google.com/go/asset v1.13.0/go.mod h1:WQAMyYek/b7NBpYq/K4KJWcRqzoalEsxz/t/dTk4THw=
cloud.google.com/go/asset v1.14.1/go.mod h1:4bEJ3dnHCqWCDbWJ/6Vn7GVI9LerSi7Rfdi03hd+WTQ=
cloud.google.com/go/assuredworkloads v1.5.0/go.mod h1:n8HOZ6pff6re5KYfBXcFvSViQjDwxFkAkmUFffJRbbY=
cloud.google.com/go/assuredworkloads v1.6.0/go.mod h1:yo2YOk37Yc89Rsd5QMVECvjaMKymF9OP+QXWlKXUkXw=
cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI=
cloud.google.com/go/assuredworkloads v1.8.0/go.mod h1:AsX2cqyNCOvEQC8RMPnoc0yEarXQk6WEKkxYfL6kGIo=
cloud.google.com/go/assuredworkloads v1.9.0/go.mod h1:kFuI1P78bplYtT77Tb1hi0FMxM0vVpRC7VVoJC3ZoT0=
cloud.google.com/go/assuredworkloads v1.10.0/go.mod h1:kwdUQuXcedVdsIaKgKTp9t0UJkE5+PAVNhdQm4ZVq2E=
cloud.google.com/go/assuredworkloads v1.11.1/go.mod h1:+F04I52Pgn5nmPG36CWFtxmav6+7Q+c5QyJoL18Lry0=
cloud.google.com/go/automl v1.5.0/go.mod h1:34EjfoFGMZ5sgJ9EoLsRtdPSNZLcfflJR39VbVNS2M0=
cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8=
cloud.google.com/go/automl v1.7.0/go.mod h1:RL9MYCCsJEOmt0Wf3z9uzG0a7adTT1fe+aObgSpkCt8=
cloud.google.com/go/automl v1.8.0/go.mod h1:xWx7G/aPEe/NP+qzYXktoBSDfjO+vnKMGgsApGJJquM=
cloud.google.com/go/automl v1.12.0/go.mod h1:tWDcHDp86aMIuHmyvjuKeeHEGq76lD7ZqfGLN6B0NuU=
cloud.google.com/go/automl v1.13.1/go.mod h1:1aowgAHWYZU27MybSCFiukPO7xnyawv7pt3zK4bheQE=
cloud.google.com/go/baremetalsolution v0.3.0/go.mod h1:XOrocE+pvK1xFfleEnShBlNAXf+j5blPPxrhjKgnIFc=
cloud.google.com/go/baremetalsolution v0.4.0/go.mod h1:BymplhAadOO/eBa7KewQ0Ppg4A4Wplbn+PsFKRLo0uI=
cloud.google.com/go/baremetalsolution v0.5.0/go.mod h1:dXGxEkmR9BMwxhzBhV0AioD0ULBmuLZI8CdwalUxuss=
cloud.google.com/go/batch v0.3.0/go.mod h1:TR18ZoAekj1GuirsUsR1ZTKN3FC/4UDnScjT8NXImFE=
cloud.google.com/go/batch v0.4.0/go.mod h1:WZkHnP43R/QCGQsZ+0JyG4i79ranE2u8xvjq/9+STPE=
cloud.google.com/go/batch v0.7.0/go.mod h1:vLZN95s6teRUqRQ4s3RLDsH8PvboqBK+rn1oevL159g=
cloud.google.com/go/beyondcorp v0.2.0/go.mod h1:TB7Bd+EEtcw9PCPQhCJtJGjk/7TC6ckmnSFS+xwTfm4=
cloud.google.com/go/beyondcorp v0.3.0/go.mod h1:E5U5lcrcXMsCuoDNyGrpyTm/hn7ne941Jz2vmksAxW8=
cloud.google.com/go/beyondcorp v0.4.0/go.mod h1:3ApA0mbhHx6YImmuubf5pyW8srKnCEPON32/5hj+RmM=
cloud.google.com/go/beyondcorp v0.5.0/go.mod h1:uFqj9X+dSfrheVp7ssLTaRHd2EHqSL4QZmH4e8WXGGU=
cloud.google.com/go/beyondcorp v0.6.1/go.mod h1:YhxDWw946SCbmcWo3fAhw3V4XZMSpQ/VYfcKGAEU8/4=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=
cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA=
cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw=
cloud.google.com/go/bigquery v1.44.0/go.mod h1:0Y33VqXTEsbamHJvJHdFmtqHvMIY28aK1+dFsvaChGc=
cloud.google.com/go/bigquery v1.47.0/go.mod h1:sA9XOgy0A8vQK9+MWhEQTY6Tix87M/ZurWFIxmF9I/E=
cloud.google.com/go/bigquery v1.48.0/go.mod h1:QAwSz+ipNgfL5jxiaK7weyOhzdoAy1zFm0Nf1fysJac=
cloud.google.com/go/bigquery v1.49.0/go.mod h1:Sv8hMmTFFYBlt/ftw2uN6dFdQPzBlREY9yBh7Oy7/4Q=
cloud.google.com/go/bigquery v1.50.0/go.mod h1:YrleYEh2pSEbgTBZYMJ5SuSr0ML3ypjRB1zgf7pvQLU=
cloud.google.com/go/bigquery v1.52.0/go.mod h1:3b/iXjRQGU4nKa87cXeg6/gogLjO8C6PmuM8i5Bi/u4=
cloud.google.com/go/billing v1.4.0/go.mod h1:g9IdKBEFlItS8bTtlrZdVLWSSdSyFUZKXNS02zKMOZY=
cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s=
cloud.google.com/go/billing v1.6.0/go.mod h1:WoXzguj+BeHXPbKfNWkqVtDdzORazmCjraY+vrxcyvI=
cloud.google.com/go/billing v1.7.0/go.mod h1:q457N3Hbj9lYwwRbnlD7vUpyjq6u5U1RAOArInEiD5Y=
cloud.google.com/go/billing v1.12.0/go.mod h1:yKrZio/eu+okO/2McZEbch17O5CB5NpZhhXG6Z766ss=
cloud.google.com/go/billing v1.13.0/go.mod h1:7kB2W9Xf98hP9Sr12KfECgfGclsH3CQR0R08tnRlRbc=
cloud.google.com/go/billing v1.16.0/go.mod h1:y8vx09JSSJG02k5QxbycNRrN7FGZB6F3CAcgum7jvGA=
cloud.google.com/go/binaryauthorization v1.1.0/go.mod h1:xwnoWu3Y84jbuHa0zd526MJYmtnVXn0syOjaJgy4+dM=
cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI=
cloud.google.com/go/binaryauthorization v1.3.0/go.mod h1:lRZbKgjDIIQvzYQS1p99A7/U1JqvqeZg0wiI5tp6tg0=
cloud.google.com/go/binaryauthorization v1.4.0/go.mod h1:tsSPQrBd77VLplV70GUhBf/Zm3FsKmgSqgm4UmiDItk=
cloud.google.com/go/binaryauthorization v1.5.0/go.mod h1:OSe4OU1nN/VswXKRBmciKpo9LulY41gch5c68htf3/Q=
cloud.google.com/go/binaryauthorization v1.6.1/go.mod h1:TKt4pa8xhowwffiBmbrbcxijJRZED4zrqnwZ1lKH51U=
cloud.google.com/go/certificatemanager v1.3.0/go.mod h1:n6twGDvcUBFu9uBgt4eYvvf3sQ6My8jADcOVwHmzadg=
cloud.google.com/go/certificatemanager v1.4.0/go.mod h1:vowpercVFyqs8ABSmrdV+GiFf2H/ch3KyudYQEMM590=
cloud.google.com/go/certificatemanager v1.6.0/go.mod h1:3Hh64rCKjRAX8dXgRAyOcY5vQ/fE1sh8o+Mdd6KPgY8=
cloud.google.com/go/certificatemanager v1.7.1/go.mod h1:iW8J3nG6SaRYImIa+wXQ0g8IgoofDFRp5UMzaNk1UqI=
cloud.google.com/go/channel v1.8.0/go.mod h1:W5SwCXDJsq/rg3tn3oG0LOxpAo6IMxNa09ngphpSlnk=
cloud.google.com/go/channel v1.9.0/go.mod h1:jcu05W0my9Vx4mt3/rEHpfxc9eKi9XwsdDL8yBMbKUk=
cloud.google.com/go/channel v1.11.0/go.mod h1:IdtI0uWGqhEeatSB62VOoJ8FSUhJ9/+iGkJVqp74CGE=
cloud.google.com/go/channel v1.12.0/go.mod h1:VkxCGKASi4Cq7TbXxlaBezonAYpp1GCnKMY6tnMQnLU=
cloud.google.com/go/channel v1.16.0/go.mod h1:eN/q1PFSl5gyu0dYdmxNXscY/4Fi7ABmeHCJNf/oHmc=
cloud.google.com/go/cloudbuild v1.3.0/go.mod h1:WequR4ULxlqvMsjDEEEFnOG5ZSRSgWOywXYDb1vPE6U=
cloud.google.com/go/cloudbuild v1.4.0/go.mod h1:5Qwa40LHiOXmz3386FrjrYM93rM/hdRr7b53sySrTqA=
cloud.google.com/go/cloudbuild v1.6.0/go.mod h1:UIbc/w9QCbH12xX+ezUsgblrWv+Cv4Tw83GiSMHOn9M=
cloud.google.com/go/cloudbuild v1.7.0/go.mod h1:zb5tWh2XI6lR9zQmsm1VRA+7OCuve5d8S+zJUul8KTg=
cloud.google.com/go/cloudbuild v1.9.0/go.mod h1:qK1d7s4QlO0VwfYn5YuClDGg2hfmLZEb4wQGAbIgL1s=
cloud.google.com/go/cloudbuild v1.10.1/go.mod h1:lyJg7v97SUIPq4RC2sGsz/9tNczhyv2AjML/ci4ulzU=
cloud.google.com/go/clouddms v1.3.0/go.mod h1:oK6XsCDdW4Ib3jCCBugx+gVjevp2TMXFtgxvPSee3OM=
cloud.google.com/go/clouddms v1.4.0/go.mod h1:Eh7sUGCC+aKry14O1NRljhjyrr0NFC0G2cjwX0cByRk=
cloud.google.com/go/clouddms v1.5.0/go.mod h1:QSxQnhikCLUw13iAbffF2CZxAER3xDGNHjsTAkQJcQA=
cloud.google.com/go/clouddms v1.6.1/go.mod h1:Ygo1vL52Ov4TBZQquhz5fiw2CQ58gvu+PlS6PVXCpZI=
cloud.google.com/go/cloudtasks v1.5.0/go.mod h1:fD92REy1x5woxkKEkLdvavGnPJGEn8Uic9nWuLzqCpY=
cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI=
cloud.google.com/go/cloudtasks v1.7.0/go.mod h1:ImsfdYWwlWNJbdgPIIGJWC+gemEGTBK/SunNQQNCAb4=
cloud.google.com/go/cloudtasks v1.8.0/go.mod h1:gQXUIwCSOI4yPVK7DgTVFiiP0ZW/eQkydWzwVMdHxrI=
cloud.google.com/go/cloudtasks v1.9.0/go.mod h1:w+EyLsVkLWHcOaqNEyvcKAsWp9p29dL6uL9Nst1cI7Y=
cloud.google.com/go/cloudtasks v1.10.0/go.mod h1:NDSoTLkZ3+vExFEWu2UJV1arUyzVDAiZtdWcsUyNwBs=
cloud.google.com/go/cloudtasks v1.11.1/go.mod h1:a9udmnou9KO2iulGscKR0qBYjreuX8oHwpmFsKspEvM=
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow=
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM=
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M=
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s=
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU=
cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U=
cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU=
cloud.google.com/go/compute v1.12.0/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU=
cloud.google.com/go/compute v1.13.0/go.mod h1:5aPTS0cUNMIc1CE546K+Th6weJUNQErARyZtRXDJ8GE=
cloud.google.com/go/compute v1.14.0/go.mod h1:YfLtxrj9sU4Yxv+sXzZkyPjEyPBZfXHUvjxega5vAdo=
cloud.google.com/go/compute v1.15.1/go.mod h1:bjjoF/NtFUrkD/urWfdHaKuOPDR5nWIs63rR+SXhcpA=
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
cloud.google.com/go/compute v1.19.0/go.mod h1:rikpw2y+UMidAe9tISo04EHNOIf42RLYF/q8Bs93scU=
cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
cloud.google.com/go/compute v1.19.3/go.mod h1:qxvISKp/gYnXkSAD1ppcSOveRAmzxicEv/JlizULFrI=
cloud.google.com/go/compute v1.20.1/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU=
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/contactcenterinsights v1.3.0/go.mod h1:Eu2oemoePuEFc/xKFPjbTuPSj0fYJcPls9TFlPNnHHY=
cloud.google.com/go/contactcenterinsights v1.4.0/go.mod h1:L2YzkGbPsv+vMQMCADxJoT9YiTTnSEd6fEvCeHTYVck=
cloud.google.com/go/contactcenterinsights v1.6.0/go.mod h1:IIDlT6CLcDoyv79kDv8iWxMSTZhLxSCofVV5W6YFM/w=
cloud.google.com/go/contactcenterinsights v1.9.1/go.mod h1:bsg/R7zGLYMVxFFzfh9ooLTruLRCG9fnzhH9KznHhbM=
cloud.google.com/go/container v1.6.0/go.mod h1:Xazp7GjJSeUYo688S+6J5V+n/t+G5sKBTFkKNudGRxg=
cloud.google.com/go/container v1.7.0/go.mod h1:Dp5AHtmothHGX3DwwIHPgq45Y8KmNsgN3amoYfxVkLo=
cloud.google.com/go/container v1.13.1/go.mod h1:6wgbMPeQRw9rSnKBCAJXnds3Pzj03C4JHamr8asWKy4=
cloud.google.com/go/container v1.14.0/go.mod h1:3AoJMPhHfLDxLvrlVWaK57IXzaPnLaZq63WX59aQBfM=
cloud.google.com/go/container v1.15.0/go.mod h1:ft+9S0WGjAyjDggg5S06DXj+fHJICWg8L7isCQe9pQA=
cloud.google.com/go/container v1.22.1/go.mod h1:lTNExE2R7f+DLbAN+rJiKTisauFCaoDq6NURZ83eVH4=
cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I=
cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4=
cloud.google.com/go/containeranalysis v0.7.0/go.mod h1:9aUL+/vZ55P2CXfuZjS4UjQ9AgXoSw8Ts6lemfmxBxI=
cloud.google.com/go/containeranalysis v0.9.0/go.mod h1:orbOANbwk5Ejoom+s+DUCTTJ7IBdBQJDcSylAx/on9s=
cloud.google.com/go/containeranalysis v0.10.1/go.mod h1:Ya2jiILITMY68ZLPaogjmOMNkwsDrWBSTyBubGXO7j0=
cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0=
cloud.google.com/go/datacatalog v1.5.0/go.mod h1:M7GPLNQeLfWqeIm3iuiruhPzkt65+Bx8dAKvScX8jvs=
cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc=
cloud.google.com/go/datacatalog v1.7.0/go.mod h1:9mEl4AuDYWw81UGc41HonIHH7/sn52H0/tc8f8ZbZIE=
cloud.google.com/go/datacatalog v1.8.0/go.mod h1:KYuoVOv9BM8EYz/4eMFxrr4DUKhGIOXxZoKYF5wdISM=
cloud.google.com/go/datacatalog v1.8.1/go.mod h1:RJ58z4rMp3gvETA465Vg+ag8BGgBdnRPEMMSTr5Uv+M=
cloud.google.com/go/datacatalog v1.12.0/go.mod h1:CWae8rFkfp6LzLumKOnmVh4+Zle4A3NXLzVJ1d1mRm0=
cloud.google.com/go/datacatalog v1.13.0/go.mod h1:E4Rj9a5ZtAxcQJlEBTLgMTphfP11/lNaAshpoBgemX8=
cloud.google.com/go/datacatalog v1.14.0/go.mod h1:h0PrGtlihoutNMp/uvwhawLQ9+c63Kz65UFqh49Yo+E=
cloud.google.com/go/datacatalog v1.14.1/go.mod h1:d2CevwTG4yedZilwe+v3E3ZBDRMobQfSG/a6cCCN5R4=
cloud.google.com/go/dataflow v0.6.0/go.mod h1:9QwV89cGoxjjSR9/r7eFDqqjtvbKxAK2BaYU6PVk9UM=
cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ=
cloud.google.com/go/dataflow v0.8.0/go.mod h1:Rcf5YgTKPtQyYz8bLYhFoIV/vP39eL7fWNcSOyFfLJE=
cloud.google.com/go/dataflow v0.9.1/go.mod h1:Wp7s32QjYuQDWqJPFFlnBKhkAtiFpMTdg00qGbnIHVw=
cloud.google.com/go/dataform v0.3.0/go.mod h1:cj8uNliRlHpa6L3yVhDOBrUXH+BPAO1+KFMQQNSThKo=
cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE=
cloud.google.com/go/dataform v0.5.0/go.mod h1:GFUYRe8IBa2hcomWplodVmUx/iTL0FrsauObOM3Ipr0=
cloud.google.com/go/dataform v0.6.0/go.mod h1:QPflImQy33e29VuapFdf19oPbE4aYTJxr31OAPV+ulA=
cloud.google.com/go/dataform v0.7.0/go.mod h1:7NulqnVozfHvWUBpMDfKMUESr+85aJsC/2O0o3jWPDE=
cloud.google.com/go/dataform v0.8.1/go.mod h1:3BhPSiw8xmppbgzeBbmDvmSWlwouuJkXsXsb8UBih9M=
cloud.google.com/go/datafusion v1.4.0/go.mod h1:1Zb6VN+W6ALo85cXnM1IKiPw+yQMKMhB9TsTSRDo/38=
cloud.google.com/go/datafusion v1.5.0/go.mod h1:Kz+l1FGHB0J+4XF2fud96WMmRiq/wj8N9u007vyXZ2w=
cloud.google.com/go/datafusion v1.6.0/go.mod h1:WBsMF8F1RhSXvVM8rCV3AeyWVxcC2xY6vith3iw3S+8=
cloud.google.com/go/datafusion v1.7.1/go.mod h1:KpoTBbFmoToDExJUso/fcCiguGDk7MEzOWXUsJo0wsI=
cloud.google.com/go/datalabeling v0.5.0/go.mod h1:TGcJ0G2NzcsXSE/97yWjIZO0bXj0KbVlINXMG9ud42I=
cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ=
cloud.google.com/go/datalabeling v0.7.0/go.mod h1:WPQb1y08RJbmpM3ww0CSUAGweL0SxByuW2E+FU+wXcM=
cloud.google.com/go/datalabeling v0.8.1/go.mod h1:XS62LBSVPbYR54GfYQsPXZjTW8UxCK2fkDciSrpRFdY=
cloud.google.com/go/dataplex v1.3.0/go.mod h1:hQuRtDg+fCiFgC8j0zV222HvzFQdRd+SVX8gdmFcZzA=
cloud.google.com/go/dataplex v1.4.0/go.mod h1:X51GfLXEMVJ6UN47ESVqvlsRplbLhcsAt0kZCCKsU0A=
cloud.google.com/go/dataplex v1.5.2/go.mod h1:cVMgQHsmfRoI5KFYq4JtIBEUbYwc3c7tXmIDhRmNNVQ=
cloud.google.com/go/dataplex v1.6.0/go.mod h1:bMsomC/aEJOSpHXdFKFGQ1b0TDPIeL28nJObeO1ppRs=
cloud.google.com/go/dataplex v1.8.1/go.mod h1:7TyrDT6BCdI8/38Uvp0/ZxBslOslP2X2MPDucliyvSE=
cloud.google.com/go/dataproc v1.7.0/go.mod h1:CKAlMjII9H90RXaMpSxQ8EU6dQx6iAYNPcYPOkSbi8s=
cloud.google.com/go/dataproc v1.8.0/go.mod h1:5OW+zNAH0pMpw14JVrPONsxMQYMBqJuzORhIBfBn9uI=
cloud.google.com/go/dataproc v1.12.0/go.mod h1:zrF3aX0uV3ikkMz6z4uBbIKyhRITnxvr4i3IjKsKrw4=
cloud.google.com/go/dataqna v0.5.0/go.mod h1:90Hyk596ft3zUQ8NkFfvICSIfHFh1Bc7C4cK3vbhkeo=
cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA=
cloud.google.com/go/dataqna v0.7.0/go.mod h1:Lx9OcIIeqCrw1a6KdO3/5KMP1wAmTc0slZWwP12Qq3c=
cloud.google.com/go/dataqna v0.8.1/go.mod h1:zxZM0Bl6liMePWsHA8RMGAfmTG34vJMapbHAxQ5+WA8=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/datastore v1.10.0/go.mod h1:PC5UzAmDEkAmkfaknstTYbNpgE49HAgW2J1gcgUfmdM=
cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c=
cloud.google.com/go/datastore v1.12.0/go.mod h1:KjdB88W897MRITkvWWJrg2OUtrR5XVj1EoLgSp6/N70=
cloud.google.com/go/datastream v1.2.0/go.mod h1:i/uTP8/fZwgATHS/XFu0TcNUhuA0twZxxQ3EyCUQMwo=
cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ=
cloud.google.com/go/datastream v1.4.0/go.mod h1:h9dpzScPhDTs5noEMQVWP8Wx8AFBRyS0s8KWPx/9r0g=
cloud.google.com/go/datastream v1.5.0/go.mod h1:6TZMMNPwjUqZHBKPQ1wwXpb0d5VDVPl2/XoS5yi88q4=
cloud.google.com/go/datastream v1.6.0/go.mod h1:6LQSuswqLa7S4rPAOZFVjHIG3wJIjZcZrw8JDEDJuIs=
cloud.google.com/go/datastream v1.7.0/go.mod h1:uxVRMm2elUSPuh65IbZpzJNMbuzkcvu5CjMqVIUHrww=
cloud.google.com/go/datastream v1.9.1/go.mod h1:hqnmr8kdUBmrnk65k5wNRoHSCYksvpdZIcZIEl8h43Q=
cloud.google.com/go/deploy v1.4.0/go.mod h1:5Xghikd4VrmMLNaF6FiRFDlHb59VM59YoDQnOUdsH/c=
cloud.google.com/go/deploy v1.5.0/go.mod h1:ffgdD0B89tToyW/U/D2eL0jN2+IEV/3EMuXHA0l4r+s=
cloud.google.com/go/deploy v1.6.0/go.mod h1:f9PTHehG/DjCom3QH0cntOVRm93uGBDt2vKzAPwpXQI=
cloud.google.com/go/deploy v1.8.0/go.mod h1:z3myEJnA/2wnB4sgjqdMfgxCA0EqC3RBTNcVPs93mtQ=
cloud.google.com/go/deploy v1.11.0/go.mod h1:tKuSUV5pXbn67KiubiUNUejqLs4f5cxxiCNCeyl0F2g=
cloud.google.com/go/dialogflow v1.15.0/go.mod h1:HbHDWs33WOGJgn6rfzBW1Kv807BE3O1+xGbn59zZWI4=
cloud.google.com/go/dialogflow v1.16.1/go.mod h1:po6LlzGfK+smoSmTBnbkIZY2w8ffjz/RcGSS+sh1el0=
cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8=
cloud.google.com/go/dialogflow v1.18.0/go.mod h1:trO7Zu5YdyEuR+BhSNOqJezyFQ3aUzz0njv7sMx/iek=
cloud.google.com/go/dialogflow v1.19.0/go.mod h1:JVmlG1TwykZDtxtTXujec4tQ+D8SBFMoosgy+6Gn0s0=
cloud.google.com/go/dialogflow v1.29.0/go.mod h1:b+2bzMe+k1s9V+F2jbJwpHPzrnIyHihAdRFMtn2WXuM=
cloud.google.com/go/dialogflow v1.31.0/go.mod h1:cuoUccuL1Z+HADhyIA7dci3N5zUssgpBJmCzI6fNRB4=
cloud.google.com/go/dialogflow v1.32.0/go.mod h1:jG9TRJl8CKrDhMEcvfcfFkkpp8ZhgPz3sBGmAUYJ2qE=
cloud.google.com/go/dialogflow v1.38.0/go.mod h1:L7jnH+JL2mtmdChzAIcXQHXMvQkE3U4hTaNltEuxXn4=
cloud.google.com/go/dlp v1.6.0/go.mod h1:9eyB2xIhpU0sVwUixfBubDoRwP+GjeUoxxeueZmqvmM=
cloud.google.com/go/dlp v1.7.0/go.mod h1:68ak9vCiMBjbasxeVD17hVPxDEck+ExiHavX8kiHG+Q=
cloud.google.com/go/dlp v1.9.0/go.mod h1:qdgmqgTyReTz5/YNSSuueR8pl7hO0o9bQ39ZhtgkWp4=
cloud.google.com/go/dlp v1.10.1/go.mod h1:IM8BWz1iJd8njcNcG0+Kyd9OPnqnRNkDV8j42VT5KOI=
cloud.google.com/go/documentai v1.7.0/go.mod h1:lJvftZB5NRiFSX4moiye1SMxHx0Bc3x1+p9e/RfXYiU=
cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU=
cloud.google.com/go/documentai v1.9.0/go.mod h1:FS5485S8R00U10GhgBC0aNGrJxBP8ZVpEeJ7PQDZd6k=
cloud.google.com/go/documentai v1.10.0/go.mod h1:vod47hKQIPeCfN2QS/jULIvQTugbmdc0ZvxxfQY1bg4=
cloud.google.com/go/documentai v1.16.0/go.mod h1:o0o0DLTEZ+YnJZ+J4wNfTxmDVyrkzFvttBXXtYRMHkM=
cloud.google.com/go/documentai v1.18.0/go.mod h1:F6CK6iUH8J81FehpskRmhLq/3VlwQvb7TvwOceQ2tbs=
cloud.google.com/go/documentai v1.20.0/go.mod h1:yJkInoMcK0qNAEdRnqY/D5asy73tnPe88I1YTZT+a8E=
cloud.google.com/go/domains v0.6.0/go.mod h1:T9Rz3GasrpYk6mEGHh4rymIhjlnIuB4ofT1wTxDeT4Y=
cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg=
cloud.google.com/go/domains v0.8.0/go.mod h1:M9i3MMDzGFXsydri9/vW+EWz9sWb4I6WyHqdlAk0idE=
cloud.google.com/go/domains v0.9.1/go.mod h1:aOp1c0MbejQQ2Pjf1iJvnVyT+z6R6s8pX66KaCSDYfE=
cloud.google.com/go/edgecontainer v0.1.0/go.mod h1:WgkZ9tp10bFxqO8BLPqv2LlfmQF1X8lZqwW4r1BTajk=
cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w=
cloud.google.com/go/edgecontainer v0.3.0/go.mod h1:FLDpP4nykgwwIfcLt6zInhprzw0lEi2P1fjO6Ie0qbc=
cloud.google.com/go/edgecontainer v1.0.0/go.mod h1:cttArqZpBB2q58W/upSG++ooo6EsblxDIolxa3jSjbY=
cloud.google.com/go/edgecontainer v1.1.1/go.mod h1:O5bYcS//7MELQZs3+7mabRqoWQhXCzenBu0R8bz2rwk=
cloud.google.com/go/errorreporting v0.3.0/go.mod h1:xsP2yaAp+OAW4OIm60An2bbLpqIhKXdWR/tawvl7QzU=
cloud.google.com/go/essentialcontacts v1.3.0/go.mod h1:r+OnHa5jfj90qIfZDO/VztSFqbQan7HV75p8sA+mdGI=
cloud.google.com/go/essentialcontacts v1.4.0/go.mod h1:8tRldvHYsmnBCHdFpvU+GL75oWiBKl80BiqlFh9tp+8=
cloud.google.com/go/essentialcontacts v1.5.0/go.mod h1:ay29Z4zODTuwliK7SnX8E86aUF2CTzdNtvv42niCX0M=
cloud.google.com/go/essentialcontacts v1.6.2/go.mod h1:T2tB6tX+TRak7i88Fb2N9Ok3PvY3UNbUsMag9/BARh4=
cloud.google.com/go/eventarc v1.7.0/go.mod h1:6ctpF3zTnaQCxUjHUdcfgcA1A2T309+omHZth7gDfmc=
cloud.google.com/go/eventarc v1.8.0/go.mod h1:imbzxkyAU4ubfsaKYdQg04WS1NvncblHEup4kvF+4gw=
cloud.google.com/go/eventarc v1.10.0/go.mod h1:u3R35tmZ9HvswGRBnF48IlYgYeBcPUCjkr4BTdem2Kw=
cloud.google.com/go/eventarc v1.11.0/go.mod h1:PyUjsUKPWoRBCHeOxZd/lbOOjahV41icXyUY5kSTvVY=
cloud.google.com/go/eventarc v1.12.1/go.mod h1:mAFCW6lukH5+IZjkvrEss+jmt2kOdYlN8aMx3sRJiAI=
cloud.google.com/go/filestore v1.3.0/go.mod h1:+qbvHGvXU1HaKX2nD0WEPo92TP/8AQuCVEBXNY9z0+w=
cloud.google.com/go/filestore v1.4.0/go.mod h1:PaG5oDfo9r224f8OYXURtAsY+Fbyq/bLYoINEK8XQAI=
cloud.google.com/go/filestore v1.5.0/go.mod h1:FqBXDWBp4YLHqRnVGveOkHDf8svj9r5+mUDLupOWEDs=
cloud.google.com/go/filestore v1.6.0/go.mod h1:di5unNuss/qfZTw2U9nhFqo8/ZDSc466dre85Kydllg=
cloud.google.com/go/filestore v1.7.1/go.mod h1:y10jsorq40JJnjR/lQ8AfFbbcGlw3g+Dp8oN7i7FjV4=
cloud.google.com/go/firestore v1.9.0/go.mod h1:HMkjKHNTtRyZNiMzu7YAsLr9K3X2udY2AMwDaMEQiiE=
cloud.google.com/go/firestore v1.11.0/go.mod h1:b38dKhgzlmNNGTNZZwe7ZRFEuRab1Hay3/DBsIGKKy4=
cloud.google.com/go/functions v1.6.0/go.mod h1:3H1UA3qiIPRWD7PeZKLvHZ9SaQhR26XIJcC0A5GbvAk=
cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg=
cloud.google.com/go/functions v1.8.0/go.mod h1:RTZ4/HsQjIqIYP9a9YPbU+QFoQsAlYgrwOXJWHn1POY=
cloud.google.com/go/functions v1.9.0/go.mod h1:Y+Dz8yGguzO3PpIjhLTbnqV1CWmgQ5UwtlpzoyquQ08=
cloud.google.com/go/functions v1.10.0/go.mod h1:0D3hEOe3DbEvCXtYOZHQZmD+SzYsi1YbI7dGvHfldXw=
cloud.google.com/go/functions v1.12.0/go.mod h1:AXWGrF3e2C/5ehvwYo/GH6O5s09tOPksiKhz+hH8WkA=
cloud.google.com/go/functions v1.13.0/go.mod h1:EU4O007sQm6Ef/PwRsI8N2umygGqPBS/IZQKBQBcJ3c=
cloud.google.com/go/functions v1.15.1/go.mod h1:P5yNWUTkyU+LvW/S9O6V+V423VZooALQlqoXdoPz5AE=
cloud.google.com/go/gaming v1.5.0/go.mod h1:ol7rGcxP/qHTRQE/RO4bxkXq+Fix0j6D4LFPzYTIrDM=
cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA=
cloud.google.com/go/gaming v1.7.0/go.mod h1:LrB8U7MHdGgFG851iHAfqUdLcKBdQ55hzXy9xBJz0+w=
cloud.google.com/go/gaming v1.8.0/go.mod h1:xAqjS8b7jAVW0KFYeRUxngo9My3f33kFmua++Pi+ggM=
cloud.google.com/go/gaming v1.9.0/go.mod h1:Fc7kEmCObylSWLO334NcO+O9QMDyz+TKC4v1D7X+Bc0=
cloud.google.com/go/gaming v1.10.1/go.mod h1:XQQvtfP8Rb9Rxnxm5wFVpAp9zCQkJi2bLIb7iHGwB3s=
cloud.google.com/go/gkebackup v0.2.0/go.mod h1:XKvv/4LfG829/B8B7xRkk8zRrOEbKtEam6yNfuQNH60=
cloud.google.com/go/gkebackup v0.3.0/go.mod h1:n/E671i1aOQvUxT541aTkCwExO/bTer2HDlj4TsBRAo=
cloud.google.com/go/gkebackup v0.4.0/go.mod h1:byAyBGUwYGEEww7xsbnUTBHIYcOPy/PgUWUtOeRm9Vg=
cloud.google.com/go/gkeconnect v0.5.0/go.mod h1:c5lsNAg5EwAy7fkqX/+goqFsU1Da/jQFqArp+wGNr/o=
cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A=
cloud.google.com/go/gkeconnect v0.7.0/go.mod h1:SNfmVqPkaEi3bF/B3CNZOAYPYdg7sU+obZ+QTky2Myw=
cloud.google.com/go/gkeconnect v0.8.1/go.mod h1:KWiK1g9sDLZqhxB2xEuPV8V9NYzrqTUmQR9shJHpOZw=
cloud.google.com/go/gkehub v0.9.0/go.mod h1:WYHN6WG8w9bXU0hqNxt8rm5uxnk8IH+lPY9J2TV7BK0=
cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0=
cloud.google.com/go/gkehub v0.11.0/go.mod h1:JOWHlmN+GHyIbuWQPl47/C2RFhnFKH38jH9Ascu3n0E=
cloud.google.com/go/gkehub v0.12.0/go.mod h1:djiIwwzTTBrF5NaXCGv3mf7klpEMcST17VBTVVDcuaw=
cloud.google.com/go/gkehub v0.14.1/go.mod h1:VEXKIJZ2avzrbd7u+zeMtW00Y8ddk/4V9511C9CQGTY=
cloud.google.com/go/gkemulticloud v0.3.0/go.mod h1:7orzy7O0S+5kq95e4Hpn7RysVA7dPs8W/GgfUtsPbrA=
cloud.google.com/go/gkemulticloud v0.4.0/go.mod h1:E9gxVBnseLWCk24ch+P9+B2CoDFJZTyIgLKSalC7tuI=
cloud.google.com/go/gkemulticloud v0.5.0/go.mod h1:W0JDkiyi3Tqh0TJr//y19wyb1yf8llHVto2Htf2Ja3Y=
cloud.google.com/go/gkemulticloud v0.6.1/go.mod h1:kbZ3HKyTsiwqKX7Yw56+wUGwwNZViRnxWK2DVknXWfw=
cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc=
cloud.google.com/go/grafeas v0.3.0/go.mod h1:P7hgN24EyONOTMyeJH6DxG4zD7fwiYa5Q6GUgyFSOU8=
cloud.google.com/go/gsuiteaddons v1.3.0/go.mod h1:EUNK/J1lZEZO8yPtykKxLXI6JSVN2rg9bN8SXOa0bgM=
cloud.google.com/go/gsuiteaddons v1.4.0/go.mod h1:rZK5I8hht7u7HxFQcFei0+AtfS9uSushomRlg+3ua1o=
cloud.google.com/go/gsuiteaddons v1.5.0/go.mod h1:TFCClYLd64Eaa12sFVmUyG62tk4mdIsI7pAnSXRkcFo=
cloud.google.com/go/gsuiteaddons v1.6.1/go.mod h1:CodrdOqRZcLp5WOwejHWYBjZvfY0kOphkAKpF/3qdZY=
cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c=
cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY=
cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc=
cloud.google.com/go/iam v0.6.0/go.mod h1:+1AH33ueBne5MzYccyMHtEKqLE4/kJOibtffMHDMFMc=
cloud.google.com/go/iam v0.7.0/go.mod h1:H5Br8wRaDGNc8XP3keLc4unfUUZeyH3Sfl9XpQEYOeg=
cloud.google.com/go/iam v0.8.0/go.mod h1:lga0/y3iH6CX7sYqypWJ33hf7kkfXJag67naqGESjkE=
cloud.google.com/go/iam v0.11.0/go.mod h1:9PiLDanza5D+oWFZiH1uG+RnRCfEGKoyl6yo4cgWZGY=
cloud.google.com/go/iam v0.12.0/go.mod h1:knyHGviacl11zrtZUoDuYpDgLjvr28sLQaG0YB2GYAY=
cloud.google.com/go/iam v0.13.0/go.mod h1:ljOg+rcNfzZ5d6f1nAUJ8ZIxOaZUVoS14bKCtaLZ/D0=
cloud.google.com/go/iam v1.0.1/go.mod h1:yR3tmSL8BcZB4bxByRv2jkSIahVmCtfKZwLYGBalRE8=
cloud.google.com/go/iam v1.1.0/go.mod h1:nxdHjaKfCr7fNYx/HJMM8LgiMugmveWlkatear5gVyk=
cloud.google.com/go/iap v1.4.0/go.mod h1:RGFwRJdihTINIe4wZ2iCP0zF/qu18ZwyKxrhMhygBEc=
cloud.google.com/go/iap v1.5.0/go.mod h1:UH/CGgKd4KyohZL5Pt0jSKE4m3FR51qg6FKQ/z/Ix9A=
cloud.google.com/go/iap v1.6.0/go.mod h1:NSuvI9C/j7UdjGjIde7t7HBz+QTwBcapPE07+sSRcLk=
cloud.google.com/go/iap v1.7.0/go.mod h1:beqQx56T9O1G1yNPph+spKpNibDlYIiIixiqsQXxLIo=
cloud.google.com/go/iap v1.7.1/go.mod h1:WapEwPc7ZxGt2jFGB/C/bm+hP0Y6NXzOYGjpPnmMS74=
cloud.google.com/go/iap v1.8.1/go.mod h1:sJCbeqg3mvWLqjZNsI6dfAtbbV1DL2Rl7e1mTyXYREQ=
cloud.google.com/go/ids v1.1.0/go.mod h1:WIuwCaYVOzHIj2OhN9HAwvW+DBdmUAdcWlFxRl+KubM=
cloud.google.com/go/ids v1.2.0/go.mod h1:5WXvp4n25S0rA/mQWAg1YEEBBq6/s+7ml1RDCW1IrcY=
cloud.google.com/go/ids v1.3.0/go.mod h1:JBdTYwANikFKaDP6LtW5JAi4gubs57SVNQjemdt6xV4=
cloud.google.com/go/ids v1.4.1/go.mod h1:np41ed8YMU8zOgv53MMMoCntLTn2lF+SUzlM+O3u/jw=
cloud.google.com/go/iot v1.3.0/go.mod h1:r7RGh2B61+B8oz0AGE+J72AhA0G7tdXItODWsaA2oLs=
cloud.google.com/go/iot v1.4.0/go.mod h1:dIDxPOn0UvNDUMD8Ger7FIaTuvMkj+aGk94RPP0iV+g=
cloud.google.com/go/iot v1.5.0/go.mod h1:mpz5259PDl3XJthEmh9+ap0affn/MqNSP4My77Qql9o=
cloud.google.com/go/iot v1.6.0/go.mod h1:IqdAsmE2cTYYNO1Fvjfzo9po179rAtJeVGUvkLN3rLE=
cloud.google.com/go/iot v1.7.1/go.mod h1:46Mgw7ev1k9KqK1ao0ayW9h0lI+3hxeanz+L1zmbbbk=
cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA=
cloud.google.com/go/kms v1.5.0/go.mod h1:QJS2YY0eJGBg3mnDfuaCyLauWwBJiHRboYxJ++1xJNg=
cloud.google.com/go/kms v1.6.0/go.mod h1:Jjy850yySiasBUDi6KFUwUv2n1+o7QZFyuUJg6OgjA0=
cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4jMAg=
cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w=
cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24=
cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI=
cloud.google.com/go/kms v1.11.0/go.mod h1:hwdiYC0xjnWsKQQCQQmIQnS9asjYVSK6jtXm+zFqXLM=
cloud.google.com/go/kms v1.12.1/go.mod h1:c9J991h5DTl+kg7gi3MYomh12YEENGrf48ee/N/2CDM=
cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE=
cloud.google.com/go/language v1.8.0/go.mod h1:qYPVHf7SPoNNiCL2Dr0FfEFNil1qi3pQEyygwpgVKB8=
cloud.google.com/go/language v1.9.0/go.mod h1:Ns15WooPM5Ad/5no/0n81yUetis74g3zrbeJBE+ptUY=
cloud.google.com/go/language v1.10.1/go.mod h1:CPp94nsdVNiQEt1CNjF5WkTcisLiHPyIbMhvR8H2AW0=
cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8=
cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08=
cloud.google.com/go/lifesciences v0.8.0/go.mod h1:lFxiEOMqII6XggGbOnKiyZ7IBwoIqA84ClvoezaA/bo=
cloud.google.com/go/lifesciences v0.9.1/go.mod h1:hACAOd1fFbCGLr/+weUKRAJas82Y4vrL3O5326N//Wc=
cloud.google.com/go/logging v1.6.1/go.mod h1:5ZO0mHHbvm8gEmeEUHrmDlTDSu5imF6MUP9OfilNXBw=
cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeNqVNkzY8M=
cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=
cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
cloud.google.com/go/longrunning v0.4.2/go.mod h1:OHrnaYyLUV6oqwh0xiS7e5sLQhP1m0QU9R+WhGDMgIQ=
cloud.google.com/go/longrunning v0.5.0/go.mod h1:0JNuqRShmscVAhIACGtskSAWtqtOoPkwP0YF1oVEchc=
cloud.google.com/go/longrunning v0.5.1/go.mod h1:spvimkwdz6SPWKEt/XBij79E9fiTkHSQl/fRUUQJYJc=
cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE=
cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=
cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=
cloud.google.com/go/managedidentities v1.6.1/go.mod h1:h/irGhTN2SkZ64F43tfGPMbHnypMbu4RB3yl8YcuEak=
cloud.google.com/go/maps v0.1.0/go.mod h1:BQM97WGyfw9FWEmQMpZ5T6cpovXXSd1cGmFma94eubI=
cloud.google.com/go/maps v0.6.0/go.mod h1:o6DAMMfb+aINHz/p/jbcY+mYeXBoZoxTfdSQ8VAJaCw=
cloud.google.com/go/maps v0.7.0/go.mod h1:3GnvVl3cqeSvgMcpRlQidXsPYuDGQ8naBis7MVzpXsY=
cloud.google.com/go/mediatranslation v0.5.0/go.mod h1:jGPUhGTybqsPQn91pNXw0xVHfuJ3leR1wj37oU3y1f4=
cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w=
cloud.google.com/go/mediatranslation v0.7.0/go.mod h1:LCnB/gZr90ONOIQLgSXagp8XUW1ODs2UmUMvcgMfI2I=
cloud.google.com/go/mediatranslation v0.8.1/go.mod h1:L/7hBdEYbYHQJhX2sldtTO5SZZ1C1vkapubj0T2aGig=
cloud.google.com/go/memcache v1.4.0/go.mod h1:rTOfiGZtJX1AaFUrOgsMHX5kAzaTQ8azHiuDoTPzNsE=
cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM=
cloud.google.com/go/memcache v1.6.0/go.mod h1:XS5xB0eQZdHtTuTF9Hf8eJkKtR3pVRCcvJwtm68T3rA=
cloud.google.com/go/memcache v1.7.0/go.mod h1:ywMKfjWhNtkQTxrWxCkCFkoPjLHPW6A7WOTVI8xy3LY=
cloud.google.com/go/memcache v1.9.0/go.mod h1:8oEyzXCu+zo9RzlEaEjHl4KkgjlNDaXbCQeQWlzNFJM=
cloud.google.com/go/memcache v1.10.1/go.mod h1:47YRQIarv4I3QS5+hoETgKO40InqzLP6kpNLvyXuyaA=
cloud.google.com/go/metastore v1.5.0/go.mod h1:2ZNrDcQwghfdtCwJ33nM0+GrBGlVuh8rakL3vdPY3XY=
cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s=
cloud.google.com/go/metastore v1.7.0/go.mod h1:s45D0B4IlsINu87/AsWiEVYbLaIMeUSoxlKKDqBGFS8=
cloud.google.com/go/metastore v1.8.0/go.mod h1:zHiMc4ZUpBiM7twCIFQmJ9JMEkDSyZS9U12uf7wHqSI=
cloud.google.com/go/metastore v1.10.0/go.mod h1:fPEnH3g4JJAk+gMRnrAnoqyv2lpUCqJPWOodSaf45Eo=
cloud.google.com/go/metastore v1.11.1/go.mod h1:uZuSo80U3Wd4zi6C22ZZliOUJ3XeM/MlYi/z5OAOWRA=
cloud.google.com/go/monitoring v1.7.0/go.mod h1:HpYse6kkGo//7p6sT0wsIC6IBDET0RhIsnmlA53dvEk=
cloud.google.com/go/monitoring v1.8.0/go.mod h1:E7PtoMJ1kQXWxPjB6mv2fhC5/15jInuulFdYYtlcvT4=
cloud.google.com/go/monitoring v1.12.0/go.mod h1:yx8Jj2fZNEkL/GYZyTLS4ZtZEZN8WtDEiEqG4kLK50w=
cloud.google.com/go/monitoring v1.13.0/go.mod h1:k2yMBAB1H9JT/QETjNkgdCGD9bPF712XiLTVr+cBrpw=
cloud.google.com/go/monitoring v1.15.1/go.mod h1:lADlSAlFdbqQuwwpaImhsJXu1QSdd3ojypXrFSMr2rM=
cloud.google.com/go/networkconnectivity v1.4.0/go.mod h1:nOl7YL8odKyAOtzNX73/M5/mGZgqqMeryi6UPZTk/rA=
cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o=
cloud.google.com/go/networkconnectivity v1.6.0/go.mod h1:OJOoEXW+0LAxHh89nXd64uGG+FbQoeH8DtxCHVOMlaM=
cloud.google.com/go/networkconnectivity v1.7.0/go.mod h1:RMuSbkdbPwNMQjB5HBWD5MpTBnNm39iAVpC3TmsExt8=
cloud.google.com/go/networkconnectivity v1.10.0/go.mod h1:UP4O4sWXJG13AqrTdQCD9TnLGEbtNRqjuaaA7bNjF5E=
cloud.google.com/go/networkconnectivity v1.11.0/go.mod h1:iWmDD4QF16VCDLXUqvyspJjIEtBR/4zq5hwnY2X3scM=
cloud.google.com/go/networkconnectivity v1.12.1/go.mod h1:PelxSWYM7Sh9/guf8CFhi6vIqf19Ir/sbfZRUwXh92E=
cloud.google.com/go/networkmanagement v1.4.0/go.mod h1:Q9mdLLRn60AsOrPc8rs8iNV6OHXaGcDdsIQe1ohekq8=
cloud.google.com/go/networkmanagement v1.5.0/go.mod h1:ZnOeZ/evzUdUsnvRt792H0uYEnHQEMaz+REhhzJRcf4=
cloud.google.com/go/networkmanagement v1.6.0/go.mod h1:5pKPqyXjB/sgtvB5xqOemumoQNB7y95Q7S+4rjSOPYY=
cloud.google.com/go/networkmanagement v1.8.0/go.mod h1:Ho/BUGmtyEqrttTgWEe7m+8vDdK74ibQc+Be0q7Fof0=
cloud.google.com/go/networksecurity v0.5.0/go.mod h1:xS6fOCoqpVC5zx15Z/MqkfDwH4+m/61A3ODiDV1xmiQ=
cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU=
cloud.google.com/go/networksecurity v0.7.0/go.mod h1:mAnzoxx/8TBSyXEeESMy9OOYwo1v+gZ5eMRnsT5bC8k=
cloud.google.com/go/networksecurity v0.8.0/go.mod h1:B78DkqsxFG5zRSVuwYFRZ9Xz8IcQ5iECsNrPn74hKHU=
cloud.google.com/go/networksecurity v0.9.1/go.mod h1:MCMdxOKQ30wsBI1eI659f9kEp4wuuAueoC9AJKSPWZQ=
cloud.google.com/go/notebooks v1.2.0/go.mod h1:9+wtppMfVPUeJ8fIWPOq1UnATHISkGXGqTkxeieQ6UY=
cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34=
cloud.google.com/go/notebooks v1.4.0/go.mod h1:4QPMngcwmgb6uw7Po99B2xv5ufVoIQ7nOGDyL4P8AgA=
cloud.google.com/go/notebooks v1.5.0/go.mod h1:q8mwhnP9aR8Hpfnrc5iN5IBhrXUy8S2vuYs+kBJ/gu0=
cloud.google.com/go/notebooks v1.7.0/go.mod h1:PVlaDGfJgj1fl1S3dUwhFMXFgfYGhYQt2164xOMONmE=
cloud.google.com/go/notebooks v1.8.0/go.mod h1:Lq6dYKOYOWUCTvw5t2q1gp1lAp0zxAxRycayS0iJcqQ=
cloud.google.com/go/notebooks v1.9.1/go.mod h1:zqG9/gk05JrzgBt4ghLzEepPHNwE5jgPcHZRKhlC1A8=
cloud.google.com/go/optimization v1.1.0/go.mod h1:5po+wfvX5AQlPznyVEZjGJTMr4+CAkJf2XSTQOOl9l4=
cloud.google.com/go/optimization v1.2.0/go.mod h1:Lr7SOHdRDENsh+WXVmQhQTrzdu9ybg0NecjHidBq6xs=
cloud.google.com/go/optimization v1.3.1/go.mod h1:IvUSefKiwd1a5p0RgHDbWCIbDFgKuEdB+fPPuP0IDLI=
cloud.google.com/go/optimization v1.4.1/go.mod h1:j64vZQP7h9bO49m2rVaTVoNM0vEBEN5eKPUPbZyXOrk=
cloud.google.com/go/orchestration v1.3.0/go.mod h1:Sj5tq/JpWiB//X/q3Ngwdl5K7B7Y0KZ7bfv0wL6fqVA=
cloud.google.com/go/orchestration v1.4.0/go.mod h1:6W5NLFWs2TlniBphAViZEVhrXRSMgUGDfW7vrWKvsBk=
cloud.google.com/go/orchestration v1.6.0/go.mod h1:M62Bevp7pkxStDfFfTuCOaXgaaqRAga1yKyoMtEoWPQ=
cloud.google.com/go/orchestration v1.8.1/go.mod h1:4sluRF3wgbYVRqz7zJ1/EUNc90TTprliq9477fGobD8=
cloud.google.com/go/orgpolicy v1.4.0/go.mod h1:xrSLIV4RePWmP9P3tBl8S93lTmlAxjm06NSm2UTmKvE=
cloud.google.com/go/orgpolicy v1.5.0/go.mod h1:hZEc5q3wzwXJaKrsx5+Ewg0u1LxJ51nNFlext7Tanwc=
cloud.google.com/go/orgpolicy v1.10.0/go.mod h1:w1fo8b7rRqlXlIJbVhOMPrwVljyuW5mqssvBtU18ONc=
cloud.google.com/go/orgpolicy v1.11.0/go.mod h1:2RK748+FtVvnfuynxBzdnyu7sygtoZa1za/0ZfpOs1M=
cloud.google.com/go/orgpolicy v1.11.1/go.mod h1:8+E3jQcpZJQliP+zaFfayC2Pg5bmhuLK755wKhIIUCE=
cloud.google.com/go/osconfig v1.7.0/go.mod h1:oVHeCeZELfJP7XLxcBGTMBvRO+1nQ5tFG9VQTmYS2Fs=
cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg=
cloud.google.com/go/osconfig v1.9.0/go.mod h1:Yx+IeIZJ3bdWmzbQU4fxNl8xsZ4amB+dygAwFPlvnNo=
cloud.google.com/go/osconfig v1.10.0/go.mod h1:uMhCzqC5I8zfD9zDEAfvgVhDS8oIjySWh+l4WK6GnWw=
cloud.google.com/go/osconfig v1.11.0/go.mod h1:aDICxrur2ogRd9zY5ytBLV89KEgT2MKB2L/n6x1ooPw=
cloud.google.com/go/osconfig v1.12.0/go.mod h1:8f/PaYzoS3JMVfdfTubkowZYGmAhUCjjwnjqWI7NVBc=
cloud.google.com/go/osconfig v1.12.1/go.mod h1:4CjBxND0gswz2gfYRCUoUzCm9zCABp91EeTtWXyz0tE=
cloud.google.com/go/oslogin v1.4.0/go.mod h1:YdgMXWRaElXz/lDk1Na6Fh5orF7gvmJ0FGLIs9LId4E=
cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU=
cloud.google.com/go/oslogin v1.6.0/go.mod h1:zOJ1O3+dTU8WPlGEkFSh7qeHPPSoxrcMbbK1Nm2iX70=
cloud.google.com/go/oslogin v1.7.0/go.mod h1:e04SN0xO1UNJ1M5GP0vzVBFicIe4O53FOfcixIqTyXo=
cloud.google.com/go/oslogin v1.9.0/go.mod h1:HNavntnH8nzrn8JCTT5fj18FuJLFJc4NaZJtBnQtKFs=
cloud.google.com/go/oslogin v1.10.1/go.mod h1:x692z7yAue5nE7CsSnoG0aaMbNoRJRXO4sn73R+ZqAs=
cloud.google.com/go/phishingprotection v0.5.0/go.mod h1:Y3HZknsK9bc9dMi+oE8Bim0lczMU6hrX0UpADuMefr0=
cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA=
cloud.google.com/go/phishingprotection v0.7.0/go.mod h1:8qJI4QKHoda/sb/7/YmMQ2omRLSLYSu9bU0EKCNI+Lk=
cloud.google.com/go/phishingprotection v0.8.1/go.mod h1:AxonW7GovcA8qdEk13NfHq9hNx5KPtfxXNeUxTDxB6I=
cloud.google.com/go/policytroubleshooter v1.3.0/go.mod h1:qy0+VwANja+kKrjlQuOzmlvscn4RNsAc0e15GGqfMxg=
cloud.google.com/go/policytroubleshooter v1.4.0/go.mod h1:DZT4BcRw3QoO8ota9xw/LKtPa8lKeCByYeKTIf/vxdE=
cloud.google.com/go/policytroubleshooter v1.5.0/go.mod h1:Rz1WfV+1oIpPdN2VvvuboLVRsB1Hclg3CKQ53j9l8vw=
cloud.google.com/go/policytroubleshooter v1.6.0/go.mod h1:zYqaPTsmfvpjm5ULxAyD/lINQxJ0DDsnWOP/GZ7xzBc=
cloud.google.com/go/policytroubleshooter v1.7.1/go.mod h1:0NaT5v3Ag1M7U5r0GfDCpUFkWd9YqpubBWsQlhanRv0=
cloud.google.com/go/privatecatalog v0.5.0/go.mod h1:XgosMUvvPyxDjAVNDYxJ7wBW8//hLDDYmnsNcMGq1K0=
cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI=
cloud.google.com/go/privatecatalog v0.7.0/go.mod h1:2s5ssIFO69F5csTXcwBP7NPFTZvps26xGzvQ2PQaBYg=
cloud.google.com/go/privatecatalog v0.8.0/go.mod h1:nQ6pfaegeDAq/Q5lrfCQzQLhubPiZhSaNhIgfJlnIXs=
cloud.google.com/go/privatecatalog v0.9.1/go.mod h1:0XlDXW2unJXdf9zFz968Hp35gl/bhF4twwpXZAW50JA=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=
cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI=
cloud.google.com/go/pubsub v1.27.1/go.mod h1:hQN39ymbV9geqBnfQq6Xf63yNhUAhv9CZhzp5O6qsW0=
cloud.google.com/go/pubsub v1.28.0/go.mod h1:vuXFpwaVoIPQMGXqRyUQigu/AX1S3IWugR9xznmcXX8=
cloud.google.com/go/pubsub v1.30.0/go.mod h1:qWi1OPS0B+b5L+Sg6Gmc9zD1Y+HaM0MdUr7LsupY1P4=
cloud.google.com/go/pubsub v1.32.0/go.mod h1:f+w71I33OMyxf9VpMVcZbnG5KSUkCOUHYpFd5U1GdRc=
cloud.google.com/go/pubsublite v1.5.0/go.mod h1:xapqNQ1CuLfGi23Yda/9l4bBCKz/wC3KIJ5gKcxveZg=
cloud.google.com/go/pubsublite v1.6.0/go.mod h1:1eFCS0U11xlOuMFV/0iBqw3zP12kddMeCbj/F3FSj9k=
cloud.google.com/go/pubsublite v1.7.0/go.mod h1:8hVMwRXfDfvGm3fahVbtDbiLePT3gpoiJYJY+vxWxVM=
cloud.google.com/go/pubsublite v1.8.1/go.mod h1:fOLdU4f5xldK4RGJrBMm+J7zMWNj/k4PxwEZXy39QS0=
cloud.google.com/go/recaptchaenterprise v1.3.1/go.mod h1:OdD+q+y4XGeAlxRaMn1Y7/GveP6zmq76byL6tjPE7d4=
cloud.google.com/go/recaptchaenterprise/v2 v2.1.0/go.mod h1:w9yVqajwroDNTfGuhmOjPDN//rZGySaf6PtFVcSCa7o=
cloud.google.com/go/recaptchaenterprise/v2 v2.2.0/go.mod h1:/Zu5jisWGeERrd5HnlS3EUGb/D335f9k51B/FVil0jk=
cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo=
cloud.google.com/go/recaptchaenterprise/v2 v2.4.0/go.mod h1:Am3LHfOuBstrLrNCBrlI5sbwx9LBg3te2N6hGvHn2mE=
cloud.google.com/go/recaptchaenterprise/v2 v2.5.0/go.mod h1:O8LzcHXN3rz0j+LBC91jrwI3R+1ZSZEWrfL7XHgNo9U=
cloud.google.com/go/recaptchaenterprise/v2 v2.6.0/go.mod h1:RPauz9jeLtB3JVzg6nCbe12qNoaa8pXc4d/YukAmcnA=
cloud.google.com/go/recaptchaenterprise/v2 v2.7.0/go.mod h1:19wVj/fs5RtYtynAPJdDTb69oW0vNHYDBTbB4NvMD9c=
cloud.google.com/go/recaptchaenterprise/v2 v2.7.2/go.mod h1:kR0KjsJS7Jt1YSyWFkseQ756D45kaYNTlDPPaRAvDBU=
cloud.google.com/go/recommendationengine v0.5.0/go.mod h1:E5756pJcVFeVgaQv3WNpImkFP8a+RptV6dDLGPILjvg=
cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4=
cloud.google.com/go/recommendationengine v0.7.0/go.mod h1:1reUcE3GIu6MeBz/h5xZJqNLuuVjNg1lmWMPyjatzac=
cloud.google.com/go/recommendationengine v0.8.1/go.mod h1:MrZihWwtFYWDzE6Hz5nKcNz3gLizXVIDI/o3G1DLcrE=
cloud.google.com/go/recommender v1.5.0/go.mod h1:jdoeiBIVrJe9gQjwd759ecLJbxCDED4A6p+mqoqDvTg=
cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c=
cloud.google.com/go/recommender v1.7.0/go.mod h1:XLHs/W+T8olwlGOgfQenXBTbIseGclClff6lhFVe9Bs=
cloud.google.com/go/recommender v1.8.0/go.mod h1:PkjXrTT05BFKwxaUxQmtIlrtj0kph108r02ZZQ5FE70=
cloud.google.com/go/recommender v1.9.0/go.mod h1:PnSsnZY7q+VL1uax2JWkt/UegHssxjUVVCrX52CuEmQ=
cloud.google.com/go/recommender v1.10.1/go.mod h1:XFvrE4Suqn5Cq0Lf+mCP6oBHD/yRMA8XxP5sb7Q7gpA=
cloud.google.com/go/redis v1.7.0/go.mod h1:V3x5Jq1jzUcg+UNsRvdmsfuFnit1cfe3Z/PGyq/lm4Y=
cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A=
cloud.google.com/go/redis v1.9.0/go.mod h1:HMYQuajvb2D0LvMgZmLDZW8V5aOC/WxstZHiy4g8OiA=
cloud.google.com/go/redis v1.10.0/go.mod h1:ThJf3mMBQtW18JzGgh41/Wld6vnDDc/F/F35UolRZPM=
cloud.google.com/go/redis v1.11.0/go.mod h1:/X6eicana+BWcUda5PpwZC48o37SiFVTFSs0fWAJ7uQ=
cloud.google.com/go/redis v1.13.1/go.mod h1:VP7DGLpE91M6bcsDdMuyCm2hIpB6Vp2hI090Mfd1tcg=
cloud.google.com/go/resourcemanager v1.3.0/go.mod h1:bAtrTjZQFJkiWTPDb1WBjzvc6/kifjj4QBYuKCCoqKA=
cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7LIXwrShilPh3P1tR0=
cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots=
cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo=
cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI=
cloud.google.com/go/resourcemanager v1.9.1/go.mod h1:dVCuosgrh1tINZ/RwBufr8lULmWGOkPS8gL5gqyjdT8=
cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU=
cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg=
cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA=
cloud.google.com/go/resourcesettings v1.6.1/go.mod h1:M7mk9PIZrC5Fgsu1kZJci6mpgN8o0IUzVx3eJU3y4Jw=
cloud.google.com/go/retail v1.8.0/go.mod h1:QblKS8waDmNUhghY2TI9O3JLlFk8jybHeV4BF19FrE4=
cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY=
cloud.google.com/go/retail v1.10.0/go.mod h1:2gDk9HsL4HMS4oZwz6daui2/jmKvqShXKQuB2RZ+cCc=
cloud.google.com/go/retail v1.11.0/go.mod h1:MBLk1NaWPmh6iVFSz9MeKG/Psyd7TAgm6y/9L2B4x9Y=
cloud.google.com/go/retail v1.12.0/go.mod h1:UMkelN/0Z8XvKymXFbD4EhFJlYKRx1FGhQkVPU5kF14=
cloud.google.com/go/retail v1.14.1/go.mod h1:y3Wv3Vr2k54dLNIrCzenyKG8g8dhvhncT2NcNjb/6gE=
cloud.google.com/go/run v0.2.0/go.mod h1:CNtKsTA1sDcnqqIFR3Pb5Tq0usWxJJvsWOCPldRU3Do=
cloud.google.com/go/run v0.3.0/go.mod h1:TuyY1+taHxTjrD0ZFk2iAR+xyOXEA0ztb7U3UNA0zBo=
cloud.google.com/go/run v0.8.0/go.mod h1:VniEnuBwqjigv0A7ONfQUaEItaiCRVujlMqerPPiktM=
cloud.google.com/go/run v0.9.0/go.mod h1:Wwu+/vvg8Y+JUApMwEDfVfhetv30hCG4ZwDR/IXl2Qg=
cloud.google.com/go/scheduler v1.4.0/go.mod h1:drcJBmxF3aqZJRhmkHQ9b3uSSpQoltBPGPxGAWROx6s=
cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI=
cloud.google.com/go/scheduler v1.6.0/go.mod h1:SgeKVM7MIwPn3BqtcBntpLyrIJftQISRrYB5ZtT+KOk=
cloud.google.com/go/scheduler v1.7.0/go.mod h1:jyCiBqWW956uBjjPMMuX09n3x37mtyPJegEWKxRsn44=
cloud.google.com/go/scheduler v1.8.0/go.mod h1:TCET+Y5Gp1YgHT8py4nlg2Sew8nUHMqcpousDgXJVQc=
cloud.google.com/go/scheduler v1.9.0/go.mod h1:yexg5t+KSmqu+njTIh3b7oYPheFtBWGcbVUYF1GGMIc=
cloud.google.com/go/scheduler v1.10.1/go.mod h1:R63Ldltd47Bs4gnhQkmNDse5w8gBRrhObZ54PxgR2Oo=
cloud.google.com/go/secretmanager v1.6.0/go.mod h1:awVa/OXF6IiyaU1wQ34inzQNc4ISIDIrId8qE5QGgKA=
cloud.google.com/go/secretmanager v1.8.0/go.mod h1:hnVgi/bN5MYHd3Gt0SPuTPPp5ENina1/LxM+2W9U9J4=
cloud.google.com/go/secretmanager v1.9.0/go.mod h1:b71qH2l1yHmWQHt9LC80akm86mX8AL6X1MA01dW8ht4=
cloud.google.com/go/secretmanager v1.10.0/go.mod h1:MfnrdvKMPNra9aZtQFvBcvRU54hbPD8/HayQdlUgJpU=
cloud.google.com/go/secretmanager v1.11.1/go.mod h1:znq9JlXgTNdBeQk9TBW/FnR/W4uChEKGeqQWAJ8SXFw=
cloud.google.com/go/security v1.5.0/go.mod h1:lgxGdyOKKjHL4YG3/YwIL2zLqMFCKs0UbQwgyZmfJl4=
cloud.google.com/go/security v1.7.0/go.mod h1:mZklORHl6Bg7CNnnjLH//0UlAlaXqiG7Lb9PsPXLfD0=
cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU=
cloud.google.com/go/security v1.9.0/go.mod h1:6Ta1bO8LXI89nZnmnsZGp9lVoVWXqsVbIq/t9dzI+2Q=
cloud.google.com/go/security v1.10.0/go.mod h1:QtOMZByJVlibUT2h9afNDWRZ1G96gVywH8T5GUSb9IA=
cloud.google.com/go/security v1.12.0/go.mod h1:rV6EhrpbNHrrxqlvW0BWAIawFWq3X90SduMJdFwtLB8=
cloud.google.com/go/security v1.13.0/go.mod h1:Q1Nvxl1PAgmeW0y3HTt54JYIvUdtcpYKVfIB8AOMZ+0=
cloud.google.com/go/security v1.15.1/go.mod h1:MvTnnbsWnehoizHi09zoiZob0iCHVcL4AUBj76h9fXA=
cloud.google.com/go/securitycenter v1.13.0/go.mod h1:cv5qNAqjY84FCN6Y9z28WlkKXyWsgLO832YiWwkCWcU=
cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc=
cloud.google.com/go/securitycenter v1.15.0/go.mod h1:PeKJ0t8MoFmmXLXWm41JidyzI3PJjd8sXWaVqg43WWk=
cloud.google.com/go/securitycenter v1.16.0/go.mod h1:Q9GMaLQFUD+5ZTabrbujNWLtSLZIZF7SAR0wWECrjdk=
cloud.google.com/go/securitycenter v1.18.1/go.mod h1:0/25gAzCM/9OL9vVx4ChPeM/+DlfGQJDwBy/UC8AKK0=
cloud.google.com/go/securitycenter v1.19.0/go.mod h1:LVLmSg8ZkkyaNy4u7HCIshAngSQ8EcIRREP3xBnyfag=
cloud.google.com/go/securitycenter v1.23.0/go.mod h1:8pwQ4n+Y9WCWM278R8W3nF65QtY172h4S8aXyI9/hsQ=
cloud.google.com/go/servicecontrol v1.4.0/go.mod h1:o0hUSJ1TXJAmi/7fLJAedOovnujSEvjKCAFNXPQ1RaU=
cloud.google.com/go/servicecontrol v1.5.0/go.mod h1:qM0CnXHhyqKVuiZnGKrIurvVImCs8gmqWsDoqe9sU1s=
cloud.google.com/go/servicecontrol v1.10.0/go.mod h1:pQvyvSRh7YzUF2efw7H87V92mxU8FnFDawMClGCNuAA=
cloud.google.com/go/servicecontrol v1.11.0/go.mod h1:kFmTzYzTUIuZs0ycVqRHNaNhgR+UMUpw9n02l/pY+mc=
cloud.google.com/go/servicecontrol v1.11.1/go.mod h1:aSnNNlwEFBY+PWGQ2DoM0JJ/QUXqV5/ZD9DOLB7SnUk=
cloud.google.com/go/servicedirectory v1.4.0/go.mod h1:gH1MUaZCgtP7qQiI+F+A+OpeKF/HQWgtAddhTbhL2bs=
cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg=
cloud.google.com/go/servicedirectory v1.6.0/go.mod h1:pUlbnWsLH9c13yGkxCmfumWEPjsRs1RlmJ4pqiNjVL4=
cloud.google.com/go/servicedirectory v1.7.0/go.mod h1:5p/U5oyvgYGYejufvxhgwjL8UVXjkuw7q5XcG10wx1U=
cloud.google.com/go/servicedirectory v1.8.0/go.mod h1:srXodfhY1GFIPvltunswqXpVxFPpZjf8nkKQT7XcXaY=
cloud.google.com/go/servicedirectory v1.9.0/go.mod h1:29je5JjiygNYlmsGz8k6o+OZ8vd4f//bQLtvzkPPT/s=
cloud.google.com/go/servicedirectory v1.10.1/go.mod h1:Xv0YVH8s4pVOwfM/1eMTl0XJ6bzIOSLDt8f8eLaGOxQ=
cloud.google.com/go/servicemanagement v1.4.0/go.mod h1:d8t8MDbezI7Z2R1O/wu8oTggo3BI2GKYbdG4y/SJTco=
cloud.google.com/go/servicemanagement v1.5.0/go.mod h1:XGaCRe57kfqu4+lRxaFEAuqmjzF0r+gWHjWqKqBvKFo=
cloud.google.com/go/servicemanagement v1.6.0/go.mod h1:aWns7EeeCOtGEX4OvZUWCCJONRZeFKiptqKf1D0l/Jc=
cloud.google.com/go/servicemanagement v1.8.0/go.mod h1:MSS2TDlIEQD/fzsSGfCdJItQveu9NXnUniTrq/L8LK4=
cloud.google.com/go/serviceusage v1.3.0/go.mod h1:Hya1cozXM4SeSKTAgGXgj97GlqUvF5JaoXacR1JTP/E=
cloud.google.com/go/serviceusage v1.4.0/go.mod h1:SB4yxXSaYVuUBYUml6qklyONXNLt83U0Rb+CXyhjEeU=
cloud.google.com/go/serviceusage v1.5.0/go.mod h1:w8U1JvqUqwJNPEOTQjrMHkw3IaIFLoLsPLvsE3xueec=
cloud.google.com/go/serviceusage v1.6.0/go.mod h1:R5wwQcbOWsyuOfbP9tGdAnCAc6B9DRwPG1xtWMDeuPA=
cloud.google.com/go/shell v1.3.0/go.mod h1:VZ9HmRjZBsjLGXusm7K5Q5lzzByZmJHf1d0IWHEN5X4=
cloud.google.com/go/shell v1.4.0/go.mod h1:HDxPzZf3GkDdhExzD/gs8Grqk+dmYcEjGShZgYa9URw=
cloud.google.com/go/shell v1.6.0/go.mod h1:oHO8QACS90luWgxP3N9iZVuEiSF84zNyLytb+qE2f9A=
cloud.google.com/go/shell v1.7.1/go.mod h1:u1RaM+huXFaTojTbW4g9P5emOrrmLE69KrxqQahKn4g=
cloud.google.com/go/spanner v1.41.0/go.mod h1:MLYDBJR/dY4Wt7ZaMIQ7rXOTLjYrmxLE/5ve9vFfWos=
cloud.google.com/go/spanner v1.44.0/go.mod h1:G8XIgYdOK+Fbcpbs7p2fiprDw4CaZX63whnSMLVBxjk=
cloud.google.com/go/spanner v1.45.0/go.mod h1:FIws5LowYz8YAE1J8fOS7DJup8ff7xJeetWEo5REA2M=
cloud.google.com/go/spanner v1.47.0/go.mod h1:IXsJwVW2j4UKs0eYDqodab6HgGuA1bViSqW4uH9lfUI=
cloud.google.com/go/speech v1.6.0/go.mod h1:79tcr4FHCimOp56lwC01xnt/WPJZc4v3gzyT7FoBkCM=
cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ=
cloud.google.com/go/speech v1.8.0/go.mod h1:9bYIl1/tjsAnMgKGHKmBZzXKEkGgtU+MpdDPTE9f7y0=
cloud.google.com/go/speech v1.9.0/go.mod h1:xQ0jTcmnRFFM2RfX/U+rk6FQNUF6DQlydUSyoooSpco=
cloud.google.com/go/speech v1.14.1/go.mod h1:gEosVRPJ9waG7zqqnsHpYTOoAS4KouMRLDFMekpJ0J0=
cloud.google.com/go/speech v1.15.0/go.mod h1:y6oH7GhqCaZANH7+Oe0BhgIogsNInLlz542tg3VqeYI=
cloud.google.com/go/speech v1.17.1/go.mod h1:8rVNzU43tQvxDaGvqOhpDqgkJTFowBpDvCJ14kGlJYo=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y=
cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc=
cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s=
cloud.google.com/go/storage v1.28.1/go.mod h1:Qnisd4CqDdo6BGs2AD5LLnEsmSQ80wQ5ogcBBKhU86Y=
cloud.google.com/go/storage v1.29.0/go.mod h1:4puEjyTKnku6gfKoTfNOU/W+a9JyuVNxjpS5GBrB8h4=
cloud.google.com/go/storage v1.30.1/go.mod h1:NfxhC0UJE1aXSx7CIIbCf7y9HKT7BiccwkR7+P7gN8E=
cloud.google.com/go/storagetransfer v1.5.0/go.mod h1:dxNzUopWy7RQevYFHewchb29POFv3/AaBgnhqzqiK0w=
cloud.google.com/go/storagetransfer v1.6.0/go.mod h1:y77xm4CQV/ZhFZH75PLEXY0ROiS7Gh6pSKrM8dJyg6I=
cloud.google.com/go/storagetransfer v1.7.0/go.mod h1:8Giuj1QNb1kfLAiWM1bN6dHzfdlDAVC9rv9abHot2W4=
cloud.google.com/go/storagetransfer v1.8.0/go.mod h1:JpegsHHU1eXg7lMHkvf+KE5XDJ7EQu0GwNJbbVGanEw=
cloud.google.com/go/storagetransfer v1.10.0/go.mod h1:DM4sTlSmGiNczmV6iZyceIh2dbs+7z2Ayg6YAiQlYfA=
cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw=
cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g=
cloud.google.com/go/talent v1.3.0/go.mod h1:CmcxwJ/PKfRgd1pBjQgU6W3YBwiewmUzQYH5HHmSCmM=
cloud.google.com/go/talent v1.4.0/go.mod h1:ezFtAgVuRf8jRsvyE6EwmbTK5LKciD4KVnHuDEFmOOA=
cloud.google.com/go/talent v1.5.0/go.mod h1:G+ODMj9bsasAEJkQSzO2uHQWXHHXUomArjWQQYkqK6c=
cloud.google.com/go/talent v1.6.2/go.mod h1:CbGvmKCG61mkdjcqTcLOkb2ZN1SrQI8MDyma2l7VD24=
cloud.google.com/go/texttospeech v1.4.0/go.mod h1:FX8HQHA6sEpJ7rCMSfXuzBcysDAuWusNNNvN9FELDd8=
cloud.google.com/go/texttospeech v1.5.0/go.mod h1:oKPLhR4n4ZdQqWKURdwxMy0uiTS1xU161C8W57Wkea4=
cloud.google.com/go/texttospeech v1.6.0/go.mod h1:YmwmFT8pj1aBblQOI3TfKmwibnsfvhIBzPXcW4EBovc=
cloud.google.com/go/texttospeech v1.7.1/go.mod h1:m7QfG5IXxeneGqTapXNxv2ItxP/FS0hCZBwXYqucgSk=
cloud.google.com/go/tpu v1.3.0/go.mod h1:aJIManG0o20tfDQlRIej44FcwGGl/cD0oiRyMKG19IQ=
cloud.google.com/go/tpu v1.4.0/go.mod h1:mjZaX8p0VBgllCzF6wcU2ovUXN9TONFLd7iz227X2Xg=
cloud.google.com/go/tpu v1.5.0/go.mod h1:8zVo1rYDFuW2l4yZVY0R0fb/v44xLh3llq7RuV61fPM=
cloud.google.com/go/tpu v1.6.1/go.mod h1:sOdcHVIgDEEOKuqUoi6Fq53MKHJAtOwtz0GuKsWSH3E=
cloud.google.com/go/trace v1.3.0/go.mod h1:FFUE83d9Ca57C+K8rDl/Ih8LwOzWIV1krKgxg6N0G28=
cloud.google.com/go/trace v1.4.0/go.mod h1:UG0v8UBqzusp+z63o7FK74SdFE+AXpCLdFb1rshXG+Y=
cloud.google.com/go/trace v1.8.0/go.mod h1:zH7vcsbAhklH8hWFig58HvxcxyQbaIqMarMg9hn5ECA=
cloud.google.com/go/trace v1.9.0/go.mod h1:lOQqpE5IaWY0Ixg7/r2SjixMuc6lfTFeO4QGM4dQWOk=
cloud.google.com/go/trace v1.10.1/go.mod h1:gbtL94KE5AJLH3y+WVpfWILmqgc6dXcqgNXdOPAQTYk=
cloud.google.com/go/translate v1.3.0/go.mod h1:gzMUwRjvOqj5i69y/LYLd8RrNQk+hOmIXTi9+nb3Djs=
cloud.google.com/go/translate v1.4.0/go.mod h1:06Dn/ppvLD6WvA5Rhdp029IX2Mi3Mn7fpMRLPvXT5Wg=
cloud.google.com/go/translate v1.5.0/go.mod h1:29YDSYveqqpA1CQFD7NQuP49xymq17RXNaUDdc0mNu0=
cloud.google.com/go/translate v1.6.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos=
cloud.google.com/go/translate v1.7.0/go.mod h1:lMGRudH1pu7I3n3PETiOB2507gf3HnfLV8qlkHZEyos=
cloud.google.com/go/translate v1.8.1/go.mod h1:d1ZH5aaOA0CNhWeXeC8ujd4tdCFw8XoNWRljklu5RHs=
cloud.google.com/go/video v1.8.0/go.mod h1:sTzKFc0bUSByE8Yoh8X0mn8bMymItVGPfTuUBUyRgxk=
cloud.google.com/go/video v1.9.0/go.mod h1:0RhNKFRF5v92f8dQt0yhaHrEuH95m068JYOvLZYnJSw=
cloud.google.com/go/video v1.12.0/go.mod h1:MLQew95eTuaNDEGriQdcYn0dTwf9oWiA4uYebxM5kdg=
cloud.google.com/go/video v1.13.0/go.mod h1:ulzkYlYgCp15N2AokzKjy7MQ9ejuynOJdf1tR5lGthk=
cloud.google.com/go/video v1.14.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ=
cloud.google.com/go/video v1.15.0/go.mod h1:SkgaXwT+lIIAKqWAJfktHT/RbgjSuY6DobxEp0C5yTQ=
cloud.google.com/go/video v1.17.1/go.mod h1:9qmqPqw/Ib2tLqaeHgtakU+l5TcJxCJbhFXM7UJjVzU=
cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU=
cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4=
cloud.google.com/go/videointelligence v1.8.0/go.mod h1:dIcCn4gVDdS7yte/w+koiXn5dWVplOZkE+xwG9FgK+M=
cloud.google.com/go/videointelligence v1.9.0/go.mod h1:29lVRMPDYHikk3v8EdPSaL8Ku+eMzDljjuvRs105XoU=
cloud.google.com/go/videointelligence v1.10.0/go.mod h1:LHZngX1liVtUhZvi2uNS0VQuOzNi2TkY1OakiuoUOjU=
cloud.google.com/go/videointelligence v1.11.1/go.mod h1:76xn/8InyQHarjTWsBR058SmlPCwQjgcvoW0aZykOvo=
cloud.google.com/go/vision v1.2.0/go.mod h1:SmNwgObm5DpFBme2xpyOyasvBc1aPdjvMk2bBk0tKD0=
cloud.google.com/go/vision/v2 v2.2.0/go.mod h1:uCdV4PpN1S0jyCyq8sIM42v2Y6zOLkZs+4R9LrGYwFo=
cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo=
cloud.google.com/go/vision/v2 v2.4.0/go.mod h1:VtI579ll9RpVTrdKdkMzckdnwMyX2JILb+MhPqRbPsY=
cloud.google.com/go/vision/v2 v2.5.0/go.mod h1:MmaezXOOE+IWa+cS7OhRRLK2cNv1ZL98zhqFFZaaH2E=
cloud.google.com/go/vision/v2 v2.6.0/go.mod h1:158Hes0MvOS9Z/bDMSFpjwsUrZ5fPrdwuyyvKSGAGMY=
cloud.google.com/go/vision/v2 v2.7.0/go.mod h1:H89VysHy21avemp6xcf9b9JvZHVehWbET0uT/bcuY/0=
cloud.google.com/go/vision/v2 v2.7.2/go.mod h1:jKa8oSYBWhYiXarHPvP4USxYANYUEdEsQrloLjrSwJU=
cloud.google.com/go/vmmigration v1.2.0/go.mod h1:IRf0o7myyWFSmVR1ItrBSFLFD/rJkfDCUTO4vLlJvsE=
cloud.google.com/go/vmmigration v1.3.0/go.mod h1:oGJ6ZgGPQOFdjHuocGcLqX4lc98YQ7Ygq8YQwHh9A7g=
cloud.google.com/go/vmmigration v1.5.0/go.mod h1:E4YQ8q7/4W9gobHjQg4JJSgXXSgY21nA5r8swQV+Xxc=
cloud.google.com/go/vmmigration v1.6.0/go.mod h1:bopQ/g4z+8qXzichC7GW1w2MjbErL54rk3/C843CjfY=
cloud.google.com/go/vmmigration v1.7.1/go.mod h1:WD+5z7a/IpZ5bKK//YmT9E047AD+rjycCAvyMxGJbro=
cloud.google.com/go/vmwareengine v0.1.0/go.mod h1:RsdNEf/8UDvKllXhMz5J40XxDrNJNN4sagiox+OI208=
cloud.google.com/go/vmwareengine v0.2.2/go.mod h1:sKdctNJxb3KLZkE/6Oui94iw/xs9PRNC2wnNLXsHvH8=
cloud.google.com/go/vmwareengine v0.3.0/go.mod h1:wvoyMvNWdIzxMYSpH/R7y2h5h3WFkx6d+1TIsP39WGY=
cloud.google.com/go/vmwareengine v0.4.1/go.mod h1:Px64x+BvjPZwWuc4HdmVhoygcXqEkGHXoa7uyfTgSI0=
cloud.google.com/go/vpcaccess v1.4.0/go.mod h1:aQHVbTWDYUR1EbTApSVvMq1EnT57ppDmQzZ3imqIk4w=
cloud.google.com/go/vpcaccess v1.5.0/go.mod h1:drmg4HLk9NkZpGfCmZ3Tz0Bwnm2+DKqViEpeEpOq0m8=
cloud.google.com/go/vpcaccess v1.6.0/go.mod h1:wX2ILaNhe7TlVa4vC5xce1bCnqE3AeH27RV31lnmZes=
cloud.google.com/go/vpcaccess v1.7.1/go.mod h1:FogoD46/ZU+JUBX9D606X21EnxiszYi2tArQwLY4SXs=
cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xXZmFiHmGE=
cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg=
cloud.google.com/go/webrisk v1.6.0/go.mod h1:65sW9V9rOosnc9ZY7A7jsy1zoHS5W9IAXv6dGqhMQMc=
cloud.google.com/go/webrisk v1.7.0/go.mod h1:mVMHgEYH0r337nmt1JyLthzMr6YxwN1aAIEc2fTcq7A=
cloud.google.com/go/webrisk v1.8.0/go.mod h1:oJPDuamzHXgUc+b8SiHRcVInZQuybnvEW72PqTc7sSg=
cloud.google.com/go/webrisk v1.9.1/go.mod h1:4GCmXKcOa2BZcZPn6DCEvE7HypmEJcJkr4mtM+sqYPc=
cloud.google.com/go/websecurityscanner v1.3.0/go.mod h1:uImdKm2wyeXQevQJXeh8Uun/Ym1VqworNDlBXQevGMo=
cloud.google.com/go/websecurityscanner v1.4.0/go.mod h1:ebit/Fp0a+FWu5j4JOmJEV8S8CzdTkAS77oDsiSqYWQ=
cloud.google.com/go/websecurityscanner v1.5.0/go.mod h1:Y6xdCPy81yi0SQnDY1xdNTNpfY1oAgXUlcfN3B3eSng=
cloud.google.com/go/websecurityscanner v1.6.1/go.mod h1:Njgaw3rttgRHXzwCB8kgCYqv5/rGpFCsBOvPbYgszpg=
cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0=
cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M=
cloud.google.com/go/workflows v1.8.0/go.mod h1:ysGhmEajwZxGn1OhGOGKsTXc5PyxOc0vfKf5Af+to4M=
cloud.google.com/go/workflows v1.9.0/go.mod h1:ZGkj1aFIOd9c8Gerkjjq7OW7I5+l6cSvT3ujaO/WwSA=
cloud.google.com/go/workflows v1.10.0/go.mod h1:fZ8LmRmZQWacon9UCX1r/g/DfAXx5VcPALq2CxzdePw=
cloud.google.com/go/workflows v1.11.1/go.mod h1:Z+t10G1wF7h8LgdY/EmRcQY8ptBD/nvofaL6FqlET6g=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
git.sr.ht/~sbinet/gg v0.3.1/go.mod h1:KGYtlADtqsqANL9ueOFkWymvzUvLMQllU5Ixo+8v3pc=
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk=
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw=
github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ=
github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8=
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00=
github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600=
github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4=
github.com/Microsoft/hcsshim v0.9.4 h1:mnUj0ivWy6UzbB1uLFqKR6F+ZyiDc7j4iGgHTpO+5+I=
github.com/Microsoft/hcsshim v0.9.4/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc=
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY=
github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0=
github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI=
github.com/apache/arrow/go/v12 v12.0.0/go.mod h1:d+tV/eHZZ7Dz7RPrFKtPK02tpr+c9/PEd/zm8mDS9Vg=
github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk=
github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s=
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw=
github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg=
github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc=
github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs=
github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/udpa/go v0.0.0-20220112060539-c52dc94e7fbe/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230105202645-06c439db220b/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230310173818-32f1caf87195/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU=
github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU=
github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E=
github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss=
github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI=
github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko=
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
github.com/containerd/cgroups v1.0.3 h1:ADZftAkglvCiD44c77s5YmMqaP2pzVCFZvBmAlBdAP4=
github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8=
github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw=
github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE=
github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw=
github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ=
github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU=
github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI=
github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s=
github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g=
github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c=
github.com/containerd/containerd v1.6.9 h1:IN/r8DUes/B5lEGTNfIiUkfZBtIQJGx2ai703dV6lRA=
github.com/containerd/containerd v1.6.9/go.mod h1:XVicUvkxOrftE2Q1YWUXgZwkkAxwQYNOFzYWvfVfEfQ=
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo=
github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y=
github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ=
github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
github.com/containerd/fifo v1.0.0 h1:6PirWBr9/L7GDamKr+XM0IeUFXu5mf3M/BPpH9gaLBU=
github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU=
github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk=
github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0=
github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g=
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM=
github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o=
github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8=
github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y=
github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=
github.com/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0=
github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=
github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y=
github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY=
github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY=
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0=
github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34=
github.com/envoyproxy/go-control-plane v0.11.0/go.mod h1:VnHyVMpzcLvCFt9yUz1UnCwHLhwx1WguiVDV7pTG/tI=
github.com/envoyproxy/go-control-plane v0.11.1-0.20230524094728-9239064ad72f/go.mod h1:sfYdkwUW4BA3PbKjySwjJy+O4Pu0h62rlqCMHNk+K+Q=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo=
github.com/envoyproxy/protoc-gen-validate v0.9.1/go.mod h1:OKNgG7TCp5pF4d6XftA0++PMirau2/yoOwVac3AbF2w=
github.com/envoyproxy/protoc-gen-validate v0.10.0/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
github.com/envoyproxy/protoc-gen-validate v0.10.1/go.mod h1:DRjgyB0I43LtJapqN6NiRwroiAU2PaFuvk/vjgh61ss=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA=
github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
github.com/go-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-pdf/fpdf v0.6.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw=
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0 h1:zgVt4UpGxcqVOw97aRGxT4svlcmdK35fynLNctY32zI=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v2.0.8+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/s2a-go v0.1.0/go.mod h1:OJpEgntRZo8ugHpF9hkoLJbS5dSI20XZeXJ9JVywLlM=
github.com/google/s2a-go v0.1.3/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8=
github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg=
github.com/googleapis/enterprise-certificate-proxy v0.2.1/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM=
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo=
github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY=
github.com/googleapis/gax-go/v2 v2.7.0/go.mod h1:TEop28CZZQ2y+c0VxMUmu1lV+fQx57QpBWsYpwqHJx8=
github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
github.com/googleapis/gax-go/v2 v2.8.0/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
github.com/googleapis/gax-go/v2 v2.10.0/go.mod h1:4UOEnMCrxsSqQ940WnTiD6qJ63le2ev3xfyagutxiPw=
github.com/googleapis/gax-go/v2 v2.11.0/go.mod h1:DxmR61SGKkGLa2xigwuZIQpkCI2S5iydzRfb3peWZJI=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=
github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY=
github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo=
github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
github.com/lyft/protoc-gen-star v0.6.1/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA=
github.com/lyft/protoc-gen-star/v2 v2.0.1/go.mod h1:RcCdONR2ScXaYnQC5tUzxzlpA3WVYF7/opLeUgcQs/o=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
github.com/mattn/go-sqlite3 v1.14.14/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY=
github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78=
github.com/moby/sys/mountinfo v0.6.2/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI=
github.com/moby/sys/signal v0.6.0 h1:aDpY94H8VlhTGa9sNYUFCFsMZIUh5wm0B6XkIoJj/iY=
github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg=
github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ=
github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
github.com/onsi/ginkgo/v2 v2.1.4/go.mod h1:um6tUpWM/cxCK3/FK8BXqEiUMUwRgSM4JXG47RKZmLU=
github.com/onsi/ginkgo/v2 v2.1.6/go.mod h1:MEH45j8TBi6u9BMogfbp0stKC5cdGjumZj5Y7AG4VIk=
github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8AyFNU9d0=
github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo=
github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls=
github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw=
github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
github.com/onsi/gomega v1.20.1/go.mod h1:DtrZpjmvpn2mPm4YWQa0/ALMDj9v4YxLgojwPeREyVo=
github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc=
github.com/onsi/gomega v1.22.1/go.mod h1:x6n7VNe4hw0vkyYUM4mjIXx3JbLiPaBPNgB7PRQ1tuM=
github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg=
github.com/onsi/gomega v1.24.0/go.mod h1:Z/NWtiqwBrwUt4/2loMmHL63EDLnYHmVbuBpDr2vQAg=
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
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.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 h1:rc3tiVYb5z54aKaDfakKn0dDjIyPpTtszkjuMzyt7ec=
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.1.2 h1:2VSZwLx5k/BfsBxMMipG/LYUnmqOD/BPkIVgQUcTlLw=
github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb h1:1xSVPOd7/UA+39/hXEGnBJ13p6JFB0E1EvQFlrRDOXI=
github.com/opencontainers/runtime-spec v1.0.3-0.20220825212826-86290f6a00fb/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/runtime-tools v0.9.0/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/opencontainers/selinux v1.10.2 h1:NFy2xCsjn7+WspbfZkUd5zyVeisV7VFbPSP96+8/ha4=
github.com/opencontainers/selinux v1.10.2/go.mod h1:cARutUbaUrlRClyvxOICCgKixCs6L05aUsohzA3EkHQ=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4=
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
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=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ=
go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg=
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.opentelemetry.io/proto/otlp v0.19.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
golang.org/x/exp v0.0.0-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20220827204233-334a2380cb91/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI=
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
golang.org/x/oauth2 v0.4.0/go.mod h1:RznEsdpjGAINPTOF0UH/t+xJ75L18YO3Ho6Pyn+uRec=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/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-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220624220833-87e55d714810/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.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20190927191325-030b2cf1153e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s=
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
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=
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=
gonum.org/v1/gonum v0.11.0/go.mod h1:fSG4YDCxxUZQJ7rKsQrj0gMOg00Il0Z96/qMA4bVQhA=
gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
gonum.org/v1/plot v0.10.1/go.mod h1:VZW5OlhkL1mysU9vaqNHnsy86inf6Ot+jB3r+BczCEo=
google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=
google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=
google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU=
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k=
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE=
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g=
google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA=
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8=
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs=
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA=
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw=
google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg=
google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o=
google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g=
google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw=
google.golang.org/api v0.95.0/go.mod h1:eADj+UBuxkh5zlrSntJghuNeg8HwQ1w5lTKkuqaETEI=
google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s=
google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08=
google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70=
google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo=
google.golang.org/api v0.103.0/go.mod h1:hGtW6nK1AC+d9si/UBhw8Xli+QMOf6xyNAyJw4qU9w0=
google.golang.org/api v0.106.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/api v0.107.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/api v0.108.0/go.mod h1:2Ts0XTHNVWxypznxWOYUeI4g3WdP9Pk2Qk58+a/O9MY=
google.golang.org/api v0.110.0/go.mod h1:7FC4Vvx1Mooxh8C5HWjzZHcavuS2f6pmJpZx60ca7iI=
google.golang.org/api v0.111.0/go.mod h1:qtFHvU9mhgTJegR31csQ+rwxyUTHOKFqCKWp1J0fdw0=
google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
google.golang.org/api v0.118.0/go.mod h1:76TtD3vkgmZ66zZzp72bUUklpmQmKlhh6sYtIjYK+5E=
google.golang.org/api v0.122.0/go.mod h1:gcitW0lvnyWjSp9nKxAbdHKIZ6vF4aajGueeslZOyms=
google.golang.org/api v0.124.0/go.mod h1:xu2HQurE5gi/3t1aFCvhPD781p0a3p11sdunTJ2BlP4=
google.golang.org/api v0.125.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
google.golang.org/api v0.126.0/go.mod h1:mBwVAtz+87bEN6CbA1GtZPDOqY2R5ONPqJeIlvyo4Aw=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s=
google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0=
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24=
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k=
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo=
google.golang.org/genproto v0.0.0-20220502173005-c8bf987b8c21/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4=
google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA=
google.golang.org/genproto v0.0.0-20220722212130-b98a9ff5e252/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE=
google.golang.org/genproto v0.0.0-20220801145646-83ce21fca29f/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc=
google.golang.org/genproto v0.0.0-20220815135757-37a418bb8959/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/genproto v0.0.0-20220817144833-d7fd3f11b9b1/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/genproto v0.0.0-20220829144015-23454907ede3/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/genproto v0.0.0-20220829175752-36a9c930ecbf/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk=
google.golang.org/genproto v0.0.0-20220913154956-18f8339a66a5/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/genproto v0.0.0-20220914142337-ca0e39ece12f/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/genproto v0.0.0-20220915135415-7fd63a7952de/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/genproto v0.0.0-20220916172020-2692e8806bfa/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/genproto v0.0.0-20220919141832-68c03719ef51/go.mod h1:0Nb8Qy+Sk5eDzHnzlStwW3itdNaWoZA5XeSG+R3JHSo=
google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw=
google.golang.org/genproto v0.0.0-20220926165614-551eb538f295/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=
google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI=
google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U=
google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM=
google.golang.org/genproto v0.0.0-20221024153911-1573dae28c9c/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
google.golang.org/genproto v0.0.0-20221027153422-115e99e71e1c/go.mod h1:CGI5F/G+E5bKwmfYo09AXuVN4dD894kIKUFmVbP2/Fo=
google.golang.org/genproto v0.0.0-20221109142239-94d6d90a7d66/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221114212237-e4508ebdbee1/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221117204609-8f9c96812029/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221118155620-16455021b5e6/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221201164419-0e50fba7f41c/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221201204527-e3fa12d562f3/go.mod h1:rZS5c/ZVYMaOGBfO68GWtjOw/eLaZM1X6iVtgjZ+EWg=
google.golang.org/genproto v0.0.0-20221202195650-67e5cbc046fd/go.mod h1:cTsE614GARnxrLsqKREzmNYJACSWWpAWdNMwnD7c2BE=
google.golang.org/genproto v0.0.0-20221227171554-f9683d7f8bef/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230110181048-76db0878b65f/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230112194545-e10362b5ecf9/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230113154510-dbe35b8444a5/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230123190316-2c411cf9d197/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230124163310-31e0e69b6fc2/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230125152338-dcaf20b6aeaa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230127162408-596548ed4efa/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230209215440-0dfe4f8abfcc/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM=
google.golang.org/genproto v0.0.0-20230216225411-c8e22ba71e44/go.mod h1:8B0gmkoRebU8ukX6HP+4wrVQUY1+6PkQ44BSyIlflHA=
google.golang.org/genproto v0.0.0-20230222225845-10f96fb3dbec/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=
google.golang.org/genproto v0.0.0-20230223222841-637eb2293923/go.mod h1:3Dl5ZL0q0isWJt+FVcfpQyirqemEuLAK/iFvg1UP1Hw=
google.golang.org/genproto v0.0.0-20230303212802-e74f57abe488/go.mod h1:TvhZT5f700eVlTNwND1xoEZQeWTB2RY/65kplwl/bFA=
google.golang.org/genproto v0.0.0-20230306155012-7f2fa6fef1f4/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/genproto v0.0.0-20230320184635-7606e756e683/go.mod h1:NWraEVixdDnqcqQ30jipen1STv2r/n24Wb7twVTGR4s=
google.golang.org/genproto v0.0.0-20230323212658-478b75c54725/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/genproto v0.0.0-20230330154414-c0448cd141ea/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/genproto v0.0.0-20230331144136-dcfb400f0633/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/genproto v0.0.0-20230403163135-c38d8f061ccd/go.mod h1:UUQDJDOlWu4KYeJZffbWgBkS1YFobzKbLVfK69pe0Ak=
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
google.golang.org/genproto v0.0.0-20230525234025-438c736192d0/go.mod h1:9ExIQyXL5hZrHzQceCwuSYwZZ5QZBazOcprJ5rgs3lY=
google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk=
google.golang.org/genproto v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:xZnkP7mREFX5MORlOPEzLMr+90PPZQ2QWzrVTWfAq64=
google.golang.org/genproto v0.0.0-20230706204954-ccb25ca9f130/go.mod h1:O9kGHb51iE/nOGvQaDUuadVYqovW56s5emA88lQnj6Y=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234020-1aefcd67740a/go.mod h1:ts19tUU+Z0ZShN1y3aPyq2+O3d5FUNNgT6FtOzmrNn8=
google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/api v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/api v0.0.0-20230629202037-9506855d4529/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
google.golang.org/genproto/googleapis/bytestream v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:ylj+BE99M198VPbBh6A8d9n3w8fChvyLK3wwBOjXBFA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234015-3fc162c6f38a/go.mod h1:xURIpW9ES5+/GZhnV6beoEtxQrnkRGIfP5VQG2tCBLc=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230629202037-9506855d4529/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d h1:pgIUhmqwKOUlnKna4r6amKdUngdL8DrkpFeV8+VBElY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230731190214-cbb8c96f2d6d/go.mod h1:TUfxEVdsvPg18p6AslUXFoLdpED4oBnGwyqk3dV1XzM=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk=
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
google.golang.org/grpc v1.53.0/go.mod h1:OnIrk0ipVdj4N5d9IUoFUx72/VlD7+jUsHwZgwSMQpw=
google.golang.org/grpc v1.54.0/go.mod h1:PUSEXI6iWghWaB6lXM4knEgpJNu2qUcKfDtNci3EC2g=
google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
google.golang.org/grpc v1.56.2/go.mod h1:I9bI3vqKfayGqPUAwGdOSu7kt6oIJLixfffKrpXqQ9s=
google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg=
google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
k8s.io/cri-api v0.25.3 h1:YaiQ05CM4+5L2DAz0KoSa4sv4/VlQvLbf3WHKICPSXs=
k8s.io/cri-api v0.25.3/go.mod h1:riC/P0yOGUf2K1735wW+CXs1aY2ctBgePtnnoFLd0dU=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
modernc.org/cc/v3 v3.36.2/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
modernc.org/cc/v3 v3.36.3/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
modernc.org/cc/v3 v3.37.0/go.mod h1:vtL+3mdHx/wcj3iEGz84rQa8vEqR6XM84v5Lcvfph20=
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=
modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=
modernc.org/ccgo/v3 v3.0.0-20220904174949-82d86e1b6d56/go.mod h1:YSXjPL62P2AMSxBphRHPn7IkzhVHqkvOnRKAKh+W6ZI=
modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
modernc.org/ccgo/v3 v3.16.8/go.mod h1:zNjwkizS+fIFDrDjIAgBSCLkWbJuHF+ar3QRn+Z9aws=
modernc.org/ccgo/v3 v3.16.9/go.mod h1:zNMzC9A9xeNUepy6KuZBbugn3c0Mc9TeiJO4lgvkJDo=
modernc.org/ccgo/v3 v3.16.13-0.20221017192402-261537637ce8/go.mod h1:fUB3Vn0nVPReA+7IG7yZDfjv1TMWjhQP8gCxrFAtL5g=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=
modernc.org/libc v1.16.17/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
modernc.org/libc v1.16.19/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
modernc.org/libc v1.17.0/go.mod h1:XsgLldpP4aWlPlsjqKRdHPqCxCjISdHfM/yeWC5GyW0=
modernc.org/libc v1.17.1/go.mod h1:FZ23b+8LjxZs7XtFMbSzL/EhPxNbfZbErxEHc7cbD9s=
modernc.org/libc v1.17.4/go.mod h1:WNg2ZH56rDEwdropAJeZPQkXmDwh+JCA1s/htl6r2fA=
modernc.org/libc v1.18.0/go.mod h1:vj6zehR5bfc98ipowQOM2nIDUZnVew/wNC/2tOGS+q0=
modernc.org/libc v1.20.3/go.mod h1:ZRfIaEkgrYgZDl6pa4W39HgN5G/yDW+NRmNKZBDFrk0=
modernc.org/libc v1.21.4/go.mod h1:przBsL5RDOZajTVslkugzLBj1evTue36jEomFQOoYuI=
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
modernc.org/memory v1.2.0/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
modernc.org/memory v1.2.1/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/memory v1.3.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
modernc.org/sqlite v1.18.1/go.mod h1:6ho+Gow7oX5V+OiOQ6Tr4xeqbx13UZ6t+Fw9IRUG4d4=
modernc.org/sqlite v1.18.2/go.mod h1:kvrTLEWgxUcHa2GfHBQtanR1H9ht3hTJNtKpzH9k1u0=
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw=
modernc.org/tcl v1.13.2/go.mod h1:7CLiGIPo1M8Rv1Mitpv5akc2+8fxUd2y2UzC/MfMzy0=
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8=
nri-0.6.1/plugins/v010-adapter/task.go 0000664 0000000 0000000 00000006026 14610311645 0017371 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"fmt"
"syscall"
"github.com/containerd/containerd"
ctrdapitypes "github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/cio"
oci "github.com/opencontainers/runtime-spec/specs-go"
)
type fakeTask struct {
id string
pid uint32
spec *oci.Spec
}
func newFakeTask(id string, pid uint32, spec *oci.Spec) containerd.Task {
return &fakeTask{
id: id,
pid: pid,
spec: spec,
}
}
func (t *fakeTask) ID() string {
return t.id
}
func (t *fakeTask) Pid() uint32 {
return t.pid
}
func (t *fakeTask) Spec(context.Context) (*oci.Spec, error) {
return t.spec, nil
}
func (t *fakeTask) Start(context.Context) error {
return nil
}
func (t *fakeTask) Delete(context.Context, ...containerd.ProcessDeleteOpts) (*containerd.ExitStatus, error) {
return nil, fmt.Errorf("unimplemented")
}
func (t *fakeTask) Kill(context.Context, syscall.Signal, ...containerd.KillOpts) error {
return fmt.Errorf("unimplemented")
}
func (t *fakeTask) Wait(context.Context) (<-chan containerd.ExitStatus, error) {
return nil, fmt.Errorf("unimplemented")
}
func (t *fakeTask) CloseIO(context.Context, ...containerd.IOCloserOpts) error {
return fmt.Errorf("unimplemented")
}
func (t *fakeTask) Resize(context.Context, uint32, uint32) error {
return fmt.Errorf("unimplemented")
}
func (t *fakeTask) IO() cio.IO {
return nil
}
func (t *fakeTask) Status(context.Context) (containerd.Status, error) {
return containerd.Status{}, fmt.Errorf("unimplemented")
}
func (t *fakeTask) Pause(context.Context) error {
return fmt.Errorf("unimplemented")
}
func (t *fakeTask) Resume(context.Context) error {
return fmt.Errorf("unimplemented")
}
func (t *fakeTask) Exec(context.Context, string, *oci.Process, cio.Creator) (containerd.Process, error) {
return nil, fmt.Errorf("unimplemented")
}
func (t *fakeTask) Pids(context.Context) ([]containerd.ProcessInfo, error) {
return nil, fmt.Errorf("unimplemented")
}
func (t *fakeTask) Checkpoint(context.Context, ...containerd.CheckpointTaskOpts) (containerd.Image, error) {
return nil, fmt.Errorf("unimplemented")
}
func (t *fakeTask) Update(context.Context, ...containerd.UpdateTaskOpts) error {
return fmt.Errorf("unimplemented")
}
func (t *fakeTask) LoadProcess(context.Context, string, cio.Attach) (containerd.Process, error) {
return nil, fmt.Errorf("unimplemented")
}
func (t *fakeTask) Metrics(context.Context) (*ctrdapitypes.Metric, error) {
return nil, fmt.Errorf("unimplemented")
}
nri-0.6.1/plugins/v010-adapter/v010-adapter.go 0000664 0000000 0000000 00000013223 14610311645 0020530 0 ustar 00root root 0000000 0000000 /*
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 main
import (
"context"
"flag"
"os"
"github.com/sirupsen/logrus"
"github.com/containerd/nri"
"github.com/containerd/nri/pkg/api"
"github.com/containerd/nri/pkg/stub"
nriv1 "github.com/containerd/nri/types/v1"
oci "github.com/opencontainers/runtime-spec/specs-go"
)
type plugin struct {
stub stub.Stub
}
var (
log *logrus.Logger
)
func (p *plugin) Configure(_ context.Context, config, runtime, version string) (stub.EventMask, error) {
log.Infof("Connected to %s/%s...", runtime, version)
return 0, nil
}
func (p *plugin) Shutdown(_ context.Context) {
log.Info("Runtime shutting down...")
}
func (p *plugin) RunPodSandbox(_ context.Context, pod *api.PodSandbox) error {
log.Infof("Started pod %s/%s...", pod.GetNamespace(), pod.GetName())
nric, err := nri.New()
if err != nil {
log.WithError(err).Errorf("unable to create nri client")
return err
}
if nric == nil {
return nil
}
ctx := context.Background()
nriSB := sandboxFromPod(pod)
task := newFakeTask(pod.GetId(), pod.GetPid(), ociSpecFromPod(pod))
if _, err := nric.InvokeWithSandbox(ctx, task, nriv1.Create, nriSB); err != nil {
log.WithError(err).Errorf("nri invoke failed")
return err
}
return nil
}
func (p *plugin) StopPodSandbox(_ context.Context, pod *api.PodSandbox) error {
log.Infof("Stopped pod %s/%s...", pod.GetNamespace(), pod.GetName())
nric, err := nri.New()
if err != nil {
log.WithError(err).Errorf("unable to create nri client")
return err
}
if nric == nil {
return nil
}
ctx := context.Background()
nriSB := sandboxFromPod(pod)
task := newFakeTask(pod.GetId(), pod.GetPid(), ociSpecFromPod(pod))
if _, err := nric.InvokeWithSandbox(ctx, task, nriv1.Delete, nriSB); err != nil {
log.WithError(err).Errorf("Failed to delete nri for %q", task.ID())
return err
}
return nil
}
func (p *plugin) StartContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) error {
log.Infof("Starting container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
nric, err := nri.New()
if err != nil {
log.WithError(err).Errorf("unable to create nri client")
return err
}
if nric == nil {
return nil
}
ctx := context.Background()
nriSB := sandboxFromPod(pod)
task := newFakeTask(ctr.GetId(), ctr.GetPid(), ociSpecFromContainer(ctr))
if _, err := nric.InvokeWithSandbox(ctx, task, nriv1.Create, nriSB); err != nil {
log.WithError(err).Errorf("nri invoke failed")
return err
}
return nil
}
func (p *plugin) StopContainer(_ context.Context, pod *api.PodSandbox, ctr *api.Container) ([]*api.ContainerUpdate, error) {
log.Infof("Stopped container %s/%s/%s...", pod.GetNamespace(), pod.GetName(), ctr.GetName())
nric, err := nri.New()
if err != nil {
log.WithError(err).Errorf("unable to create nri client")
return []*api.ContainerUpdate{}, nil
}
if nric == nil {
return []*api.ContainerUpdate{}, nil
}
ctx := context.Background()
nriSB := sandboxFromPod(pod)
task := newFakeTask(ctr.GetId(), ctr.GetPid(), ociSpecFromContainer(ctr))
if _, err := nric.InvokeWithSandbox(ctx, task, nriv1.Delete, nriSB); err != nil {
log.WithError(err).Errorf("Failed to delete nri for %q", task.ID())
}
return []*api.ContainerUpdate{}, nil
}
func (p *plugin) onClose() {
log.Infof("Connection to the runtime lost, exiting...")
os.Exit(0)
}
func sandboxFromPod(pod *api.PodSandbox) *nri.Sandbox {
return &nri.Sandbox{
ID: pod.GetId(),
Labels: pod.GetLabels(),
}
}
func ociSpecFromPod(pod *api.PodSandbox) *oci.Spec {
return &oci.Spec{
Annotations: pod.GetAnnotations(),
Linux: &oci.Linux{
Namespaces: namespacesToSlice(pod.GetLinux().GetNamespaces()),
Resources: pod.GetLinux().GetResources().ToOCI(),
CgroupsPath: pod.GetLinux().GetCgroupsPath(),
},
}
}
func ociSpecFromContainer(ctr *api.Container) *oci.Spec {
return &oci.Spec{
Annotations: ctr.GetAnnotations(),
Linux: &oci.Linux{
Namespaces: namespacesToSlice(ctr.GetLinux().GetNamespaces()),
Resources: ctr.GetLinux().GetResources().ToOCI(),
CgroupsPath: ctr.GetLinux().GetCgroupsPath(),
},
}
}
func namespacesToSlice(namespaces []*api.LinuxNamespace) []oci.LinuxNamespace {
var slice []oci.LinuxNamespace
for _, ns := range namespaces {
slice = append(slice, oci.LinuxNamespace{
Type: oci.LinuxNamespaceType(ns.Type),
Path: ns.Path,
})
}
return slice
}
func main() {
var (
pluginName string
pluginIdx string
err error
)
log = logrus.StandardLogger()
log.SetFormatter(&logrus.TextFormatter{
PadLevelText: true,
})
flag.StringVar(&pluginName, "name", "", "plugin name to register to NRI")
flag.StringVar(&pluginIdx, "idx", "", "plugin index to register to NRI")
flag.Parse()
p := &plugin{}
opts := []stub.Option{
stub.WithOnClose(p.onClose),
}
if pluginName != "" {
opts = append(opts, stub.WithPluginName(pluginName))
}
if pluginIdx != "" {
opts = append(opts, stub.WithPluginIdx(pluginIdx))
}
if p.stub, err = stub.New(p, opts...); err != nil {
log.Fatalf("failed to create plugin stub: %v", err)
}
if err = p.stub.Run(context.Background()); err != nil {
log.Errorf("plugin exited (%v)", err)
os.Exit(1)
}
}
nri-0.6.1/scripts/ 0000775 0000000 0000000 00000000000 14610311645 0013776 5 ustar 00root root 0000000 0000000 nri-0.6.1/scripts/install-protobuf 0000775 0000000 0000000 00000004601 14610311645 0017231 0 ustar 00root root 0000000 0000000 #!/usr/bin/env bash
# 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.
#
# Downloads and installs protobuf
#
set -eu -o pipefail
PROTOBUF_VERSION=3.20.1
GOARCH=$(go env GOARCH)
GOOS=$(go env GOOS)
PROTOBUF_DIR=$(mktemp -d)
case $GOARCH in
arm64)
wget -O "$PROTOBUF_DIR/protobuf" "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-linux-aarch_64.zip"
unzip "$PROTOBUF_DIR/protobuf" -d /usr/local
;;
amd64|386)
if [ "$GOOS" = windows ]; then
wget -O "$PROTOBUF_DIR/protobuf" "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-win32.zip"
elif [ "$GOOS" = linux ]; then
wget -O "$PROTOBUF_DIR/protobuf" "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-linux-x86_64.zip"
fi
unzip "$PROTOBUF_DIR/protobuf" -d /usr/local
;;
ppc64le)
wget -O "$PROTOBUF_DIR/protobuf" "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protoc-$PROTOBUF_VERSION-linux-ppcle_64.zip"
unzip "$PROTOBUF_DIR/protobuf" -d /usr/local
;;
*)
wget -O "$PROTOBUF_DIR/protobuf" "https://github.com/protocolbuffers/protobuf/releases/download/v$PROTOBUF_VERSION/protobuf-cpp-$PROTOBUF_VERSION.zip"
unzip "$PROTOBUF_DIR/protobuf" -d /usr/src/protobuf
cd "/usr/src/protobuf/protobuf-$PROTOBUF_VERSION"
./autogen.sh
./configure --disable-shared
make
make check
make install
ldconfig
;;
esac
rm -rf "$PROTOBUF_DIR"
# Download status.proto. grpc repos' one seems copied from
# https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto,
# but we use grpc's since the repos has tags/releases.
mkdir -p /usr/local/include/google/rpc
curl \
-L https://raw.githubusercontent.com/grpc/grpc/v1.45.2/src/proto/grpc/status/status.proto \
-o /usr/local/include/google/rpc/status.proto
nri-0.6.1/skel/ 0000775 0000000 0000000 00000000000 14610311645 0013245 5 ustar 00root root 0000000 0000000 nri-0.6.1/skel/skel.go 0000664 0000000 0000000 00000003336 14610311645 0014537 0 ustar 00root root 0000000 0000000 /*
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 skel
import (
"context"
"encoding/json"
"fmt"
"os"
types "github.com/containerd/nri/types/v1"
)
// Plugin for modifications of resources
type Plugin interface {
// Type or plugin name
Type() string
// Invoke the plugin
Invoke(context.Context, *types.Request) (*types.Result, error)
}
// Run the plugin from a main() function
func Run(ctx context.Context, plugin Plugin) error {
enc := json.NewEncoder(os.Stdout)
var request types.Request
if err := json.NewDecoder(os.Stdin).Decode(&request); err != nil {
return err
}
switch os.Args[1] {
case "invoke":
result, err := plugin.Invoke(ctx, &request)
if err != nil {
// if the plugin sets ErrorMessage we ignore it
result = request.NewResult(plugin.Type())
result.Error = err.Error()
}
if err := enc.Encode(result); err != nil {
return fmt.Errorf("unable to encode plugin error to stdout: %w", err)
}
default:
result := request.NewResult(plugin.Type())
result.Error = fmt.Sprintf("invalid arg %s", os.Args[1])
if err := enc.Encode(result); err != nil {
return fmt.Errorf("unable to encode invalid parameter error to stdout: %w", err)
}
}
return nil
}
nri-0.6.1/types/ 0000775 0000000 0000000 00000000000 14610311645 0013453 5 ustar 00root root 0000000 0000000 nri-0.6.1/types/v1/ 0000775 0000000 0000000 00000000000 14610311645 0014001 5 ustar 00root root 0000000 0000000 nri-0.6.1/types/v1/types.go 0000664 0000000 0000000 00000007150 14610311645 0015477 0 ustar 00root root 0000000 0000000 /*
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 v1
import (
"encoding/json"
"errors"
)
// Plugin type and configuration
type Plugin struct {
// Type of plugin
Type string `json:"type"`
// Conf for the specific plugin
Conf json.RawMessage `json:"conf,omitempty"`
}
// ConfigList for the global configuration of NRI
//
// Normally located at /etc/nri/conf.json
type ConfigList struct {
// Verion of the list
Version string `json:"version"`
// Plugins
Plugins []*Plugin `json:"plugins"`
}
// Spec for the container being processed
type Spec struct {
// Resources struct from the OCI specification
//
// Can be WindowsResources or LinuxResources
Resources json.RawMessage `json:"resources"`
// Namespaces for the container
Namespaces map[string]string `json:"namespaces,omitempty"`
// CgroupsPath for the container
CgroupsPath string `json:"cgroupsPath,omitempty"`
// Annotations passed down to the OCI runtime specification
Annotations map[string]string `json:"annotations,omitempty"`
}
// State of the request
type State string
const (
// Create the initial resource for the container
Create State = "create"
// Delete any resources for the container
Delete State = "delete"
// Update the resources for the container
Update State = "update"
// Pause action of the container
Pause State = "pause"
// Resume action for the container
Resume State = "resume"
)
// Request for a plugin invocation
type Request struct {
// Conf specific for the plugin
Conf json.RawMessage `json:"conf,omitempty"`
// Version of the plugin
Version string `json:"version"`
// State action for the request
State State `json:"state"`
// ID for the container
ID string `json:"id"`
// SandboxID for the sandbox that the request belongs to
//
// If ID and SandboxID are the same, this is a request for the sandbox
// SandboxID is empty for a non sandboxed container
SandboxID string `json:"sandboxID,omitempty"`
// Pid of the container
//
// -1 if there is no pid
Pid int `json:"pid,omitempty"`
// Spec generated from the OCI runtime specification
Spec *Spec `json:"spec"`
// Labels of a sandbox
Labels map[string]string `json:"labels,omitempty"`
// Results from previous plugins in the chain
Results []*Result `json:"results,omitempty"`
}
// IsSandbox returns true if the request is for a sandbox
func (r *Request) IsSandbox() bool {
return r.ID == r.SandboxID
}
// NewResult returns a result from the original request
func (r *Request) NewResult(plugin string) *Result {
return &Result{
Plugin: plugin,
Version: r.Version,
Metadata: make(map[string]string),
}
}
// Result of the plugin invocation
type Result struct {
// Plugin name that populated the result
Plugin string `json:"plugin"`
// Version of the plugin
Version string `json:"version"`
// Error message in case of failures
Error string `json:"error"`
// Metadata specific to actions taken by the plugin
Metadata map[string]string `json:"metadata,omitempty"`
}
// Err creates an Error object if ErrorMessage is populated
func (r *Result) Err() error {
if r.Error != "" {
return errors.New(r.Error)
}
return nil
}