From 26318197e1fcafd033310b5bb0537b59ab3b3662 Mon Sep 17 00:00:00 2001 From: ChristianZaccaria Date: Mon, 14 Aug 2023 13:16:55 +0100 Subject: [PATCH 01/10] WIP - e2e --- .github/actions/kind/action.yml | 74 ++ .github/resources-kind/kind.yaml | 31 + .github/workflows/e2e_tests.yaml | 123 +++ Dockerfile | 23 + Makefile | 386 +++++++++ go.mod | 70 ++ go.sum | 803 ++++++++++++++++++ .../templates/base-template.yaml | 16 +- .../codeflare_sdk-0.0.0.dev0-py3-none-any.whl | Bin 0 -> 39252 bytes tests/e2e/install-codeflare-sdk.sh | 23 + tests/e2e/kind.sh | 129 +++ tests/e2e/mnist.py | 160 ++++ tests/e2e/mnist_pip_requirements.txt | 3 + tests/e2e/mnist_raycluster_sdk.py | 91 ++ tests/e2e/mnist_raycluster_sdk_test.go | 207 +++++ tests/e2e/setup.sh | 58 ++ tests/e2e/support.go | 44 + tmp.yaml | 37 + tmpclusterrole.yaml | 9 + tmpclusterrolebinding.yaml | 12 + tmpingressesrole.yaml | 8 + tmpingressesroleb.yaml | 12 + 22 files changed, 2311 insertions(+), 8 deletions(-) create mode 100644 .github/actions/kind/action.yml create mode 100644 .github/resources-kind/kind.yaml create mode 100644 .github/workflows/e2e_tests.yaml create mode 100644 Dockerfile create mode 100644 Makefile create mode 100644 go.mod create mode 100644 go.sum create mode 100644 tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl create mode 100644 tests/e2e/install-codeflare-sdk.sh create mode 100755 tests/e2e/kind.sh create mode 100644 tests/e2e/mnist.py create mode 100644 tests/e2e/mnist_pip_requirements.txt create mode 100644 tests/e2e/mnist_raycluster_sdk.py create mode 100644 tests/e2e/mnist_raycluster_sdk_test.go create mode 100755 tests/e2e/setup.sh create mode 100644 tests/e2e/support.go create mode 100644 tmp.yaml create mode 100644 tmpclusterrole.yaml create mode 100644 tmpclusterrolebinding.yaml create mode 100644 tmpingressesrole.yaml create mode 100644 tmpingressesroleb.yaml diff --git a/.github/actions/kind/action.yml b/.github/actions/kind/action.yml new file mode 100644 index 000000000..f76e60af5 --- /dev/null +++ b/.github/actions/kind/action.yml @@ -0,0 +1,74 @@ +name: "Set up KinD" +description: "Step to start and configure KinD cluster" + +inputs: + kind-node-hostname: + description: "Hostname of the main kind node" + required: false + default: kind + +runs: + using: "composite" + steps: + - name: Init directories + shell: bash + run: | + TEMP_DIR="$(pwd)/tmp" + mkdir -p "${TEMP_DIR}" + echo "TEMP_DIR=${TEMP_DIR}" >> $GITHUB_ENV + + mkdir -p "$(pwd)/bin" + echo "$(pwd)/bin" >> $GITHUB_PATH + + - name: Container image registry + shell: bash + run: | + podman run -d -p 5000:5000 --name registry registry:2.8.1 + + export REGISTRY_ADDRESS=$(hostname -i):5000 + echo "REGISTRY_ADDRESS=${REGISTRY_ADDRESS}" >> $GITHUB_ENV + echo "Container image registry started at ${REGISTRY_ADDRESS}" + + KIND_CONFIG_FILE=${{ env.TEMP_DIR }}/kind.yaml + echo "KIND_CONFIG_FILE=${KIND_CONFIG_FILE}" >> $GITHUB_ENV + envsubst < .github/resources-kind/kind.yaml > ${KIND_CONFIG_FILE} + + sudo --preserve-env=REGISTRY_ADDRESS sh -c 'cat > /etc/containers/registries.conf.d/local.conf <> $GITHUB_ENV + echo "CLUSTER_HOSTNAME=${{ inputs.kind-node-hostname }}" >> $GITHUB_ENV diff --git a/.github/resources-kind/kind.yaml b/.github/resources-kind/kind.yaml new file mode 100644 index 000000000..4546589b8 --- /dev/null +++ b/.github/resources-kind/kind.yaml @@ -0,0 +1,31 @@ +# --------------------------------------------------------------------------- +# Copyright 2023. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# --------------------------------------------------------------------------- + +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + image: kindest/node:v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1 + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" +containerdConfigPatches: + - |- + [plugins."io.containerd.grpc.v1.cri".registry.mirrors."${REGISTRY_ADDRESS}"] + endpoint = ["http://${REGISTRY_ADDRESS}"] diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml new file mode 100644 index 000000000..42463583e --- /dev/null +++ b/.github/workflows/e2e_tests.yaml @@ -0,0 +1,123 @@ +name: e2e + +on: + pull_request: + branches: + - main + - 'release-*' + paths-ignore: + - 'docs/**' + - '**.adoc' + - '**.md' + - 'LICENSE' + push: + branches: + - main + - 'release-*' + paths-ignore: + - 'docs/**' + - '**.adoc' + - '**.md' + - 'LICENSE' + +concurrency: + group: ${{ github.head_ref }}-${{ github.workflow }} + cancel-in-progress: true + +jobs: + kubernetes: + + runs-on: ubuntu-20.04-4core + + steps: + - name: Cleanup + run: | + ls -lart + echo "Initial status:" + df -h + + echo "Cleaning up resources:" + sudo swapoff -a + sudo rm -f /swapfile + sudo apt clean + sudo rm -rf /usr/share/dotnet + sudo rm -rf /opt/ghc + sudo rm -rf "/usr/local/share/boost" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + docker rmi $(docker image ls -aq) + + echo "Final status:" + df -h + + - name: Checkout code + uses: actions/checkout@v2 + with: + submodules: recursive + + - name: Checkout CodeFlare operator repository + uses: actions/checkout@v3 + with: + repository: project-codeflare/codeflare-operator + path: codeflare-operator + + - name: Set Go + uses: actions/setup-go@v3 + with: + go-version: v1.19 + + - name: Set up gotestfmt + uses: gotesttools/gotestfmt-action@v2 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup and start KinD cluster + uses: ./.github/actions/kind + + - name: Deploy CodeFlare stack + id: deploy + run: | + cd codeflare-operator + echo Deploying CodeFlare operator + IMG="${REGISTRY_ADDRESS}"/codeflare-operator + make image-push -e IMG="${IMG}" + make deploy -e IMG="${IMG}" -e ENV="e2e" + kubectl wait --timeout=120s --for=condition=Available=true deployment -n openshift-operators codeflare-operator-manager + + echo Setting up CodeFlare stack + make setup-e2e + make defaults manifests fmt vet + + cd .. + + - name: Run e2e tests + run: | + export CODEFLARE_TEST_TIMEOUT_SHORT=1m + export CODEFLARE_TEST_TIMEOUT_MEDIUM=5m + export CODEFLARE_TEST_TIMEOUT_LONG=10m + + export CODEFLARE_TEST_OUTPUT_DIR=${{ env.TEMP_DIR }} + echo "CODEFLARE_TEST_OUTPUT_DIR=${CODEFLARE_TEST_OUTPUT_DIR}" >> $GITHUB_ENV + + set -euo pipefail + go test -timeout 30m -v ./tests/e2e -json 2>&1 | tee ${CODEFLARE_TEST_OUTPUT_DIR}/gotest.log | gotestfmt + + - name: Print CodeFlare operator logs + if: always() && steps.deploy.outcome == 'success' + run: | + echo "Printing CodeFlare operator logs" + kubectl logs -n openshift-operators --tail -1 -l app.kubernetes.io/name=codeflare-operator | tee ${CODEFLARE_TEST_OUTPUT_DIR}/codeflare-operator.log + + - name: Print KubeRay operator logs + if: always() && steps.deploy.outcome == 'success' + run: | + echo "Printing KubeRay operator logs" + kubectl logs -n ray-system --tail -1 -l app.kubernetes.io/name=kuberay | tee ${CODEFLARE_TEST_OUTPUT_DIR}/kuberay.log + + - name: Upload logs + uses: actions/upload-artifact@v3 + if: always() && steps.deploy.outcome == 'success' + with: + name: logs + retention-days: 10 + path: | + ${{ env.CODEFLARE_TEST_OUTPUT_DIR }}/**/*.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..2ea7fead4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +# Build the manager binary +FROM registry.access.redhat.com/ubi8/go-toolset:1.19.10-10 as builder + +WORKDIR /workspace +# Copy the Go Modules manifests +COPY go.mod go.mod +COPY go.sum go.sum +RUN go mod download + +# Copy the go source +COPY main.go main.go +COPY pkg/ pkg/ + +# Build +USER root +RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go + +FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7 +WORKDIR / +COPY --from=builder /workspace/manager . + +USER 65532:65532 +ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..c0d41155d --- /dev/null +++ b/Makefile @@ -0,0 +1,386 @@ +# VERSION defines the project version for the bundle. +# Update this value when you upgrade the version of your project. +# To re-generate a bundle for another specific version without changing the standard setup, you can: +# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=v0.0.2) +# - use environment variables to overwrite this value (e.g export VERSION=v0.0.2) +# best if we could detect this. If we cannot, we need to document it somewhere. +# then we can add a patch in the `PHONY: bundle` +# BUNDLE_VERSION is declared as bundle versioning doesn't use semver + +PREVIOUS_VERSION ?= v0.0.0-dev +VERSION ?= v0.0.0-dev +BUNDLE_VERSION ?= $(VERSION:v%=%) + +# INSTASCALE_VERSION defines the default version of the InstaScale controller +INSTASCALE_VERSION ?= v0.0.9 +INSTASCALE_REPO ?= github.com/project-codeflare/instascale + +# MCAD_VERSION defines the default version of the MCAD controller +MCAD_VERSION ?= 725a614debe3d34d1547c1659ef5ad49f8f6c5df +MCAD_REPO ?= github.com/project-codeflare/multi-cluster-app-dispatcher +# Upstream MCAD is currently only creating release tags of the form `vX.Y.Z` (i.e the version) +MCAD_CRD ?= ${MCAD_REPO}/config/crd?ref=${MCAD_VERSION} + +# KUBERAY_VERSION defines the default version of the KubeRay operator (used for testing) +KUBERAY_VERSION ?= v0.6.0 + +# RAY_VERSION defines the default version of Ray (used for testing) +RAY_VERSION ?= 2.5.0 + +# CODEFLARE_SDK_VERSION defines the default version of the CodeFlare SDK +CODEFLARE_SDK_VERSION ?= 0.8.0 + +# OPERATORS_REPO_ORG points to GitHub repository organization where bundle PR is opened against +# OPERATORS_REPO_FORK_ORG points to GitHub repository fork organization where bundle build is pushed to +OPERATORS_REPO_ORG ?= redhat-openshift-ecosystem +OPERATORS_REPO_FORK_ORG ?= project-codeflare + +# CHANNELS define the bundle channels used in the bundle. +# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") +# To re-generate a bundle for other specific channels without changing the standard setup, you can: +# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=candidate,fast,stable) +# - use environment variables to overwrite this value (e.g export CHANNELS="candidate,fast,stable") +ifneq ($(origin CHANNELS), undefined) +BUNDLE_CHANNELS := --channels=$(CHANNELS) +endif + +# DEFAULT_CHANNEL defines the default channel used in the bundle. +# Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable") +# To re-generate a bundle for any other default channel without changing the default setup, you can: +# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable) +# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable") +ifneq ($(origin DEFAULT_CHANNEL), undefined) +BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) +endif +BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) + +# IMAGE_ORG_BASE defines the base container registry and organization for container images. +IMAGE_ORG_BASE ?= quay.io/project-codeflare + +# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. +# This variable is used to construct full image tags for bundle and catalog images. +# +# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both +# codeflare.dev/codeflare-operator-bundle:$VERSION and codeflare.dev/codeflare-operator-catalog:$VERSION. +IMAGE_TAG_BASE ?= $(IMAGE_ORG_BASE)/codeflare-operator + +# RAY_IMAGE defines the default container image for Ray (used for testing) +RAY_IMAGE ?= rayproject/ray:$(RAY_VERSION) + +# BUNDLE_IMG defines the image:tag used for the bundle. +# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) +BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:$(VERSION) + +# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command +BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(BUNDLE_VERSION) $(BUNDLE_METADATA_OPTS) + +# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests +# You can enable this value if you would like to use SHA Based Digests +# To enable set flag to true +USE_IMAGE_DIGESTS ?= false +ifeq ($(USE_IMAGE_DIGESTS), true) + BUNDLE_GEN_FLAGS += --use-image-digests +endif + +# Image URL to use all building/pushing image targets +IMG ?= ${IMAGE_TAG_BASE}:${VERSION} +# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. +ENVTEST_K8S_VERSION = 1.24.2 + +# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) +ifeq (,$(shell go env GOBIN)) +GOBIN=$(shell go env GOPATH)/bin +else +GOBIN=$(shell go env GOBIN) +endif + +# Setting SHELL to bash allows bash commands to be executed by recipes. +# Options are set to exit when a recipe line exits non-zero or a piped command fails. +SHELL = /usr/bin/env bash -o pipefail +.SHELLFLAGS = -ec + +.PHONY: all +all: build + +##@ General + +# The help target prints out all targets with their descriptions organized +# beneath their categories. The categories are represented by '##@' and the +# target descriptions by '##'. The awk commands is responsible for reading the +# entire set of makefiles included in this invocation, looking for lines of the +# file as xyz: ## something, and then pretty-format the target and help. Then, +# if there's a line with ##@ something, that gets pretty-printed as a category. +# More info on the usage of ANSI control characters for terminal formatting: +# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters +# More info on the awk command: +# http://linuxcommand.org/lc3_adv_awk.php + +.PHONY: help +help: ## Display this help. + @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + +##@ Development + +DEFAULTS_TEST_FILE := tests/support/defaults.go + +.PHONY: defaults +defaults: + $(info Regenerating $(DEFAULTS_TEST_FILE)) + @echo "package support" > $(DEFAULTS_TEST_FILE) + @echo "" >> $(DEFAULTS_TEST_FILE) + @echo "// ***********************" >> $(DEFAULTS_TEST_FILE) + @echo "// DO NOT EDIT THIS FILE" >> $(DEFAULTS_TEST_FILE) + @echo "// ***********************" >> $(DEFAULTS_TEST_FILE) + @echo "" >> $(DEFAULTS_TEST_FILE) + @echo "const (" >> $(DEFAULTS_TEST_FILE) + @echo " CodeFlareSDKVersion = \"$(CODEFLARE_SDK_VERSION)\"" >> $(DEFAULTS_TEST_FILE) + @echo " RayVersion = \"$(RAY_VERSION)\"" >> $(DEFAULTS_TEST_FILE) + @echo " RayImage = \"$(RAY_IMAGE)\"" >> $(DEFAULTS_TEST_FILE) + @echo "" >> $(DEFAULTS_TEST_FILE) + @echo ")" >> $(DEFAULTS_TEST_FILE) + @echo "" >> $(DEFAULTS_TEST_FILE) + + gofmt -w $(DEFAULTS_TEST_FILE) + +.PHONY: manifests +manifests: controller-gen ## Generate RBAC objects. + $(CONTROLLER_GEN) rbac:roleName=manager-role webhook paths="./..." + +.PHONY: fmt +fmt: ## Run go fmt against code. + go fmt ./... + +.PHONY: vet +vet: ## Run go vet against code. + go vet ./... + + +##@ Build + +.PHONY: modules +modules: ## Update Go dependencies. + go get $(MCAD_REPO)@$(MCAD_VERSION) + go get $(INSTASCALE_REPO)@$(INSTASCALE_VERSION) + go get github.com/ray-project/kuberay/ray-operator + go mod tidy + +.PHONY: build +build: modules defaults fmt vet ## Build manager binary. + go build -o bin/manager main.go + +.PHONY: run +run: modules defaults manifests fmt vet ## Run a controller from your host. + go run ./main.go + +.PHONY: image-build +image-build: test-unit ## Build container image with the manager. + podman build -t ${IMG} . + +.PHONY: image-push +image-push: image-build ## Push container image with the manager. + podman push ${IMG} + +##@ Deployment + +ifndef ignore-not-found + ignore-not-found = false +endif + +.PHONY: install +install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. + $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml + $(KUSTOMIZE) build config/crd | kubectl apply -f - + git restore config/* + +.PHONY: uninstall +uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. + $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml + $(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f - + git restore config/* + +.PHONY: deploy +deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. + $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml + cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} + $(KUSTOMIZE) build config/default | kubectl apply -f - + git restore config/* + +.PHONY: undeploy +undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. + $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml + $(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f - + git restore config/* + +##@ Build Dependencies + +## Location to install dependencies to +LOCALBIN ?= $(shell pwd)/bin +$(LOCALBIN): + mkdir -p $(LOCALBIN) + +## Tool Binaries +KUSTOMIZE ?= $(LOCALBIN)/kustomize +CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen +ENVTEST ?= $(LOCALBIN)/setup-envtest +OPENSHIFT-GOIMPORTS ?= $(LOCALBIN)/openshift-goimports +OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk +GH_CLI ?= $(LOCALBIN)/gh +SED ?= /usr/bin/sed + +## Tool Versions +KUSTOMIZE_VERSION ?= v4.5.4 +CODEGEN_VERSION ?= v0.27.2 +CONTROLLER_TOOLS_VERSION ?= v0.9.2 +OPERATOR_SDK_VERSION ?= v1.27.0 +GH_CLI_VERSION ?= 2.30.0 + +KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" +.PHONY: kustomize +kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. +$(KUSTOMIZE): $(LOCALBIN) + test -s $(LOCALBIN)/kustomize || { curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); } + +GH_CLI_DL_URL := https://github.com/cli/cli/releases/download/v$(GH_CLI_VERSION) +GH_CLI_DL_FILENAME := gh_$(GH_CLI_VERSION)_$(shell go env GOOS)_$(shell go env GOARCH) +.PHONY: install-gh-cli +install-gh-cli: $(GH_CLI) +$(GH_CLI): $(LOCALBIN) + curl -L $(GH_CLI_DL_URL)/$(GH_CLI_DL_FILENAME).tar.gz --output $(GH_CLI_DL_FILENAME).tar.gz + tar -xvzf $(GH_CLI_DL_FILENAME).tar.gz + cp $(GH_CLI_DL_FILENAME)/bin/gh $(GH_CLI) + rm -rf $(GH_CLI_DL_FILENAME) + rm $(GH_CLI_DL_FILENAME).tar.gz + +.PHONY: controller-gen +controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. +$(CONTROLLER_GEN): $(LOCALBIN) + test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) + +.PHONY: envtest +envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. +$(ENVTEST): $(LOCALBIN) + test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest + +.PHONY: openshift-goimports +openshift-goimports: $(OPENSHIFT-GOIMPORTS) ## Download openshift-goimports locally if necessary. +$(OPENSHIFT-GOIMPORTS): $(LOCALBIN) + test -s $(LOCALBIN)/openshift-goimports || GOBIN=$(LOCALBIN) go install github.com/openshift-eng/openshift-goimports@latest + +OPERATOR_SDK_DL_URL := https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION) +.PHONY: install-operator-sdk +install-operator-sdk: $(OPERATOR_SDK) ## Download fixed version operator-sdk binary for consist outcome +$(OPERATOR_SDK): $(LOCALBIN) + curl -L $(OPERATOR_SDK_DL_URL)/operator-sdk_$(shell go env GOOS)_$(shell go env GOARCH) --output $(LOCALBIN)/operator-sdk + chmod +x $(OPERATOR_SDK) + +.PHONY: validate-bundle +validate-bundle: install-operator-sdk + $(OPERATOR_SDK) bundle validate ./bundle --select-optional suite=operatorframework + +.PHONY: bundle +bundle: defaults manifests kustomize install-operator-sdk ## Generate bundle manifests and metadata, then validate generated files. + $(OPERATOR_SDK) generate kustomize manifests -q + $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml + cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) + cd config/manifests && $(KUSTOMIZE) edit add patch --patch '[{"op":"add", "path":"/metadata/annotations/containerImage", "value": "$(IMG)" }]' --kind ClusterServiceVersion + cd config/manifests && $(KUSTOMIZE) edit add patch --patch '[{"op":"add", "path":"/spec/replaces", "value": "codeflare-operator.$(PREVIOUS_VERSION)" }]' --kind ClusterServiceVersion + $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) + $(MAKE) validate-bundle + git restore config/* + +.PHONY: bundle-build +bundle-build: bundle ## Build the bundle image. + podman build -f bundle.Dockerfile -t $(BUNDLE_IMG) . + +.PHONY: bundle-push +bundle-push: ## Push the bundle image. + podman push $(BUNDLE_IMG) $(BUNDLE_PUSH_OPT) + +.PHONY: openshift-community-operator-release +openshift-community-operator-release: install-gh-cli bundle ## build bundle and create PR in OpenShift community operators repository + git clone https://x-access-token:$(GH_TOKEN)@github.com/$(OPERATORS_REPO_FORK_ORG)/community-operators-prod.git + cd community-operators-prod && git remote add upstream https://github.com/$(OPERATORS_REPO_ORG)/community-operators-prod.git && git pull upstream main && git push origin main + cp -r bundle community-operators-prod/operators/codeflare-operator/$(BUNDLE_VERSION) + cd community-operators-prod && git checkout -b codeflare-release-$(BUNDLE_VERSION) && git add operators/codeflare-operator/$(BUNDLE_VERSION)/* && git commit -m "add bundle manifests codeflare version $(BUNDLE_VERSION)" --signoff && git push origin codeflare-release-$(BUNDLE_VERSION) + gh pr create --repo $(OPERATORS_REPO_ORG)/community-operators-prod --title "CodeFlare $(BUNDLE_VERSION)" --body "New release of codeflare operator" --head $(OPERATORS_REPO_FORK_ORG):codeflare-release-$(BUNDLE_VERSION) --base main + rm -rf community-operators-prod + +.PHONY: opm +OPM = ./bin/opm +opm: ## Download opm locally if necessary. +ifeq (,$(wildcard $(OPM))) +ifeq (,$(shell which opm 2>/dev/null)) + @{ \ + set -e ;\ + mkdir -p $(dir $(OPM)) ;\ + OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ + curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$${OS}-$${ARCH}-opm ;\ + chmod +x $(OPM) ;\ + } +else +OPM = $(shell which opm) +endif +endif + +# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0). +# These images MUST exist in a registry and be pull-able. +BUNDLE_IMGS ?= $(BUNDLE_IMG) + +# The image tag given to the resulting catalog image (e.g. make catalog-build CATALOG_IMG=example.com/operator-catalog:v0.2.0). +CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:$(VERSION) + +# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image. +ifneq ($(origin CATALOG_BASE_IMG), undefined) +FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) +endif + +# Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. +# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see: +# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator +.PHONY: catalog-build +catalog-build: opm ## Build a catalog image. + $(OPM) index add --container-tool podman --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT) + +# Build a catalog image by adding bundle images to existing catalog using the operator package manager tool, 'opm'. +.PHONY: catalog-build-from-index +catalog-build-from-index: opm ## Build a catalog image. + mkdir catalog + $(OPM) render $(CATALOG_BASE_IMG) -o yaml > catalog/bundles.yaml + $(OPM) render $(BUNDLE_IMG) $(OPM_BUNDLE_OPT) > catalog/codeflare-operator-bundle.yaml + $(SED) -i -E "s/(.*)(- name: codeflare-operator.$(PREVIOUS_VERSION).*)/\1- name: codeflare-operator.$(VERSION)\n replaces: codeflare-operator.$(PREVIOUS_VERSION)\n\2/" catalog/bundles.yaml + $(OPM) validate catalog + $(OPM) generate dockerfile catalog + podman build . -f catalog.Dockerfile -t $(CATALOG_IMG) + +# Push the catalog image. +.PHONY: catalog-push +catalog-push: ## Push a catalog image. + podman push $(CATALOG_IMG) $(CATALOG_PUSH_OPT) + +.PHONY: test-unit +test-unit: defaults manifests fmt vet envtest ## Run unit tests. + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $(go list ./... | grep -v /test/) -coverprofile cover.out + +.PHONY: test-e2e +test-e2e: ## Run e2e tests. + go test -timeout 30m -v ./tests/e2e -run TestMNISTRayClusterSDK + +.PHONY: kind-e2e +kind-e2e: ## Set up e2e KinD cluster. + tests/e2e/kind.sh + +.PHONY: setup-e2e +setup-e2e: ## Set up e2e tests. + KUBERAY_VERSION=$(KUBERAY_VERSION) tests/e2e/setup.sh + +.PHONY: imports +imports: openshift-goimports ## Organize imports in go files using openshift-goimports. Example: make imports + $(OPENSHIFT-GOIMPORTS) + +.PHONY: verify-imports +verify-imports: openshift-goimports ## Run import verifications. + ./hack/verify-imports.sh $(OPENSHIFT-GOIMPORTS) + +.PHONY: scorecard-bundle +scorecard-bundle: install-operator-sdk ## Run scorecard tests on bundle image. + $(OPERATOR_SDK) scorecard bundle \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 000000000..76ca0575e --- /dev/null +++ b/go.mod @@ -0,0 +1,70 @@ +module github.com/project-codeflare/codeflare-sdk + +go 1.19 + +require ( + github.com/onsi/gomega v1.27.10 + github.com/project-codeflare/codeflare-common v0.0.0-20231110155354-042fb171fcdb + github.com/project-codeflare/multi-cluster-app-dispatcher v1.37.0 + github.com/ray-project/kuberay/ray-operator v1.0.0 + k8s.io/api v0.26.3 + k8s.io/apimachinery v0.26.3 +) + +require ( + github.com/aymerick/douceur v0.2.0 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cenkalti/backoff/v4 v4.1.3 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/go-logr/logr v1.2.4 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.1 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.4.1 // indirect + github.com/golang/glog v1.0.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect + github.com/google/gnostic v0.6.9 // indirect + github.com/google/go-cmp v0.5.9 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/gorilla/css v1.0.0 // indirect + github.com/imdario/mergo v0.3.12 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect + github.com/microcosm-cc/bluemonday v1.0.18 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openshift-online/ocm-sdk-go v0.1.368 // indirect + github.com/openshift/api v0.0.0-20230213134911-7ba313770556 // indirect + github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c // indirect + github.com/prometheus/client_golang v1.14.0 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/term v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/client-go v0.26.3 // indirect + k8s.io/klog/v2 v2.100.1 // indirect + k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect + k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect + sigs.k8s.io/controller-runtime v0.14.6 // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect + sigs.k8s.io/yaml v1.3.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 000000000..c9b425cb8 --- /dev/null +++ b/go.sum @@ -0,0 +1,803 @@ +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.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +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/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/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= +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/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +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/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= +github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= +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 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +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/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +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/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +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/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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= +github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +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.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= +github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= +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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ= +github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8= +github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +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-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= +github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +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.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.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/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/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= +github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= +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.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.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/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.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/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-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/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/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/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= +github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +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/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +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.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/itchyny/gojq v0.12.7 h1:hYPTpeWfrJ1OT+2j6cvBScbhl0TkdwGM4bc66onUSOQ= +github.com/itchyny/gojq v0.12.7/go.mod h1:ZdvNHVlzPgUf8pgjnuDTmGfHA/21KoutQUJ3An/xNuw= +github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU= +github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.12.0 h1:/RvQ24k3TnNdfBSW0ou9EOi5jx2cX7zfE8n2nLKuiP0= +github.com/jackc/pgconn v1.12.0/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.0 h1:brH0pCGBDkBW07HWlN/oSBXrmo3WB0UvZd1pIuDcL8Y= +github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.11.0 h1:u4uiGPz/1hryuXzyaBhSk6dnIyyG2683olG2OV+UUgs= +github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.16.0 h1:4k1tROTJctHotannFYzu77dY3bgtMRymQP7tXQjqpPk= +github.com/jackc/pgx/v4 v4.16.0/go.mod h1:N0A9sFdWzkw/Jy1lwoiB64F2+ugFZi987zRxcPez/wI= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/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/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +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/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/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +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/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +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/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM= +github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo= +github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +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/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +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.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= +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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= +github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= +github.com/openshift-online/ocm-sdk-go v0.1.368 h1:qP+gkChV8WDwwpkUw1xUyjTXKdvrwyd70Gff2GMUSeU= +github.com/openshift-online/ocm-sdk-go v0.1.368/go.mod h1:KYOw8kAKAHyPrJcQoVR82CneQ4ofC02Na4cXXaTq4Nw= +github.com/openshift/api v0.0.0-20230213134911-7ba313770556 h1:7W2fOhJicyEff24VaF7ASNzPtYvr+iSCVft4SIBAzaE= +github.com/openshift/api v0.0.0-20230213134911-7ba313770556/go.mod h1:aQ6LDasvHMvHZXqLHnX2GRmnfTWCF/iIwz8EMTTIE9A= +github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c h1:CV76yFOTXmq9VciBR3Bve5ZWzSxdft7gaMVB3kS0rwg= +github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c/go.mod h1:lFMO8mLHXWFzSdYvGNo8ivF9SfF6zInA8ZGw4phRnUE= +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 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +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/project-codeflare/codeflare-common v0.0.0-20231110155354-042fb171fcdb h1:L2Gdr2SlvshDKZY2KK6507AwzQ1NSfRbMQuz5dOsYNM= +github.com/project-codeflare/codeflare-common v0.0.0-20231110155354-042fb171fcdb/go.mod h1:zdi2GCYJX+QyxFWyCLMoTme3NMz/aucWDJWMqKfigxk= +github.com/project-codeflare/multi-cluster-app-dispatcher v1.37.0 h1:oyhdLdc4BgA4zcH1zlRrSrYpzuVxV5QLDbyIXrwnQqs= +github.com/project-codeflare/multi-cluster-app-dispatcher v1.37.0/go.mod h1:Yge6GRNpO9YIDfeL+XOcCE9xbmfCTD5C1h5dlW87mxQ= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +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_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +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 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +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/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +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/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/ray-project/kuberay/ray-operator v1.0.0 h1:i69nvbV7az2FG41VHQgxrmhD+SUl8ca+ek4RPbSE2Q0= +github.com/ray-project/kuberay/ray-operator v1.0.0/go.mod h1:7C7ebIkxtkmOX8w1iiLrKM1j4hkZs/Guzm3WdePk/yg= +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/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +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/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +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 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.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 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +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 v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +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.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +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.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +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/atomic v1.6.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.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +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-20180904163835-0709b304e793/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-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +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-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-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220427172511-eb4f295cb31f/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +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/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.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +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-20181114220301-adae6a3d119a/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-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-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-20201021035429-f5854403a974/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.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/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-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +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-20210514164344-f6687ab2804c/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-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +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/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-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-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-20190403152447-81d4e9dc473e/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-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/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-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-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-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/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-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-20210423082822-04245dca01da/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-20210603081109-ebe580a85c40/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-20210630005230-0f9fa26af87c/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/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.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/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= +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.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-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.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/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-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-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/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-20190823170909-c4a336ef6a2f/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-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-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-20200103221440-774c71fcf114/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-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-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-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +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/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/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 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +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-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-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-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-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +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.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.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +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.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/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-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +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/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +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 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-20200615113413-eeeca48fe776/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= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +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= +k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU= +k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE= +k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k= +k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s= +k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ= +k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= +k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= +k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= +k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= +k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +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/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA= +sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= +sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/src/codeflare_sdk/templates/base-template.yaml b/src/codeflare_sdk/templates/base-template.yaml index 8e6fd0e9e..8f4575a05 100644 --- a/src/codeflare_sdk/templates/base-template.yaml +++ b/src/codeflare_sdk/templates/base-template.yaml @@ -16,21 +16,21 @@ spec: custompodresources: - replicas: 1 requests: - cpu: 2 - memory: 8G + cpu: 1 + memory: 4G nvidia.com/gpu: 0 limits: - cpu: 2 - memory: 8G + cpu: 1 + memory: 4G nvidia.com/gpu: 0 - replicas: 3 requests: - cpu: 2 - memory: 12G + cpu: 1 + memory: 4G nvidia.com/gpu: 1 limits: - cpu: 2 - memory: 12G + cpu: 1 + memory: 4G nvidia.com/gpu: 1 generictemplate: # This config demonstrates KubeRay's Ray autoscaler integration. diff --git a/tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl b/tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl new file mode 100644 index 0000000000000000000000000000000000000000..da85a840077f75398ff1b2a1d190bdf882c681e1 GIT binary patch literal 39252 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%0D~I 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 timeout: + raise TimeoutError(f"job has timed out after waiting {timeout}s") + sleep(5) + time += 5 + +print(f"Job has completed: {status.state}") + +print(job.logs()) + +cluster.down() + +if not status.state == AppState.SUCCEEDED: + exit(1) +else: + exit(0) diff --git a/tests/e2e/mnist_raycluster_sdk_test.go b/tests/e2e/mnist_raycluster_sdk_test.go new file mode 100644 index 000000000..cf4080aea --- /dev/null +++ b/tests/e2e/mnist_raycluster_sdk_test.go @@ -0,0 +1,207 @@ +/* +Copyright 2023. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package e2e + +import ( + "testing" + + . "github.com/onsi/gomega" + . "github.com/project-codeflare/codeflare-common/support" + mcadv1beta1 "github.com/project-codeflare/multi-cluster-app-dispatcher/pkg/apis/controller/v1beta1" + rayv1 "github.com/ray-project/kuberay/ray-operator/apis/ray/v1" + + batchv1 "k8s.io/api/batch/v1" + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Creates a Ray cluster, and trains the MNIST dataset using the CodeFlare SDK. +// Asserts successful completion of the training job. +// +// This covers the installation of the CodeFlare SDK, as well as the RBAC required +// for the SDK to successfully perform requests to the cluster, on behalf of the +// impersonated user. +func TestMNISTRayClusterSDK(t *testing.T) { + test := With(t) + test.T().Parallel() + + // Create a namespace + namespace := test.NewTestNamespace() + + // Test configuration + config := CreateConfigMap(test, namespace.Name, map[string][]byte{ + // SDK script + "mnist_raycluster_sdk.py": ReadFile(test, "mnist_raycluster_sdk.py"), + // pip requirements + "requirements.txt": ReadFile(test, "mnist_pip_requirements.txt"), + // MNIST training script + "mnist.py": ReadFile(test, "mnist.py"), + // SDK Wheel File + "codeflare_sdk-0.0.0.dev0-py3-none-any.whl": ReadWhlFile(test, "codeflare_sdk-0.0.0.dev0-py3-none-any.whl"), + // codeflare-sdk installation script + "install-codeflare-sdk.sh": ReadFile(test, "install-codeflare-sdk.sh"), + }) + + // Create RBAC, retrieve token for user with limited rights + policyRules := []rbacv1.PolicyRule{ + { + Verbs: []string{"get", "create", "delete", "list", "patch", "update"}, + APIGroups: []string{mcadv1beta1.GroupName}, + Resources: []string{"appwrappers"}, + }, + { + Verbs: []string{"get", "list"}, + APIGroups: []string{rayv1.GroupVersion.Group}, + Resources: []string{"rayclusters", "rayclusters/status"}, + }, + { + Verbs: []string{"get", "list"}, + APIGroups: []string{"route.openshift.io"}, + Resources: []string{"routes"}, + }, + { + Verbs: []string{"get", "list"}, + APIGroups: []string{"networking.k8s.io"}, + Resources: []string{"ingresses"}, + }, + } + + // Create cluster wide RBAC, required for SDK OpenShift check + // TODO reevaluate once SDK change OpenShift detection logic + clusterPolicyRules := []rbacv1.PolicyRule{ + { + Verbs: []string{"get", "list"}, + APIGroups: []string{"config.openshift.io"}, + Resources: []string{"ingresses"}, + ResourceNames: []string{"cluster"}, + }, + } + + sa := CreateServiceAccount(test, namespace.Name) + role := CreateRole(test, namespace.Name, policyRules) + CreateRoleBinding(test, namespace.Name, sa, role) + clusterRole := CreateClusterRole(test, clusterPolicyRules) + CreateClusterRoleBinding(test, sa, clusterRole) + + job := &batchv1.Job{ + TypeMeta: metav1.TypeMeta{ + APIVersion: batchv1.SchemeGroupVersion.String(), + Kind: "Job", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "sdk", + Namespace: namespace.Name, + }, + Spec: batchv1.JobSpec{ + Completions: Ptr(int32(1)), + Parallelism: Ptr(int32(1)), + BackoffLimit: Ptr(int32(0)), + Template: corev1.PodTemplateSpec{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "test", + // FIXME: switch to base Python image once the dependency on OpenShift CLI is removed + // See https://github.com/project-codeflare/codeflare-sdk/pull/146 + Image: "quay.io/opendatahub/notebooks:jupyter-minimal-ubi8-python-3.8-4c8f26e", + Env: []corev1.EnvVar{ + {Name: "PYTHONUSERBASE", Value: "/workdir"}, + {Name: "RAY_IMAGE", Value: GetRayImage()}, + }, + Command: []string{"/bin/sh", "-c", "cp /test/* . && chmod +x install-codeflare-sdk.sh && ./install-codeflare-sdk.sh && python mnist_raycluster_sdk.py" + " " + namespace.Name}, + // Command: []string{"/bin/sh", "-c", "pip install /test/codeflare_sdk-0.0.0.dev0-py3-none-any.whl && cp /test/* . && python mnist_raycluster_sdk.py" + " " + namespace.Name}, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "test", + MountPath: "/test", + }, + { + Name: "workdir", + MountPath: "/workdir", + }, + }, + WorkingDir: "/workdir", + SecurityContext: &corev1.SecurityContext{ + AllowPrivilegeEscalation: Ptr(false), + SeccompProfile: &corev1.SeccompProfile{ + Type: "RuntimeDefault", + }, + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + RunAsNonRoot: Ptr(true), + }, + }, + }, + Volumes: []corev1.Volume{ + { + Name: "test", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: config.Name, + }, + }, + }, + }, + { + Name: "workdir", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + }, + RestartPolicy: corev1.RestartPolicyNever, + ServiceAccountName: sa.Name, + }, + }, + }, + } + if GetClusterType(test) == KindCluster { + // Take first KinD node and redirect pod hostname requests there + node := GetNodes(test)[0] + hostname := GetClusterHostname(test) + IP := GetNodeInternalIP(test, node) + + test.T().Logf("Setting KinD cluster hostname '%s' to node IP '%s' for SDK pod", hostname, IP) + job.Spec.Template.Spec.HostAliases = []corev1.HostAlias{ + { + IP: IP, + Hostnames: []string{hostname}, + }, + } + + // Propagate hostname into Python code as env variable + hostnameEnvVar := corev1.EnvVar{Name: "CLUSTER_HOSTNAME", Value: hostname} + job.Spec.Template.Spec.Containers[0].Env = append(job.Spec.Template.Spec.Containers[0].Env, hostnameEnvVar) + } + job, err := test.Client().Core().BatchV1().Jobs(namespace.Name).Create(test.Ctx(), job, metav1.CreateOptions{}) + test.Expect(err).NotTo(HaveOccurred()) + test.T().Logf("Created Job %s/%s successfully", job.Namespace, job.Name) + + test.T().Logf("Waiting for Job %s/%s to complete", job.Namespace, job.Name) + test.Eventually(Job(test, job.Namespace, job.Name), TestTimeoutLong).Should( + Or( + WithTransform(ConditionStatus(batchv1.JobComplete), Equal(corev1.ConditionTrue)), + WithTransform(ConditionStatus(batchv1.JobFailed), Equal(corev1.ConditionTrue)), + )) + + // Assert the job has completed successfully + test.Expect(GetJob(test, job.Namespace, job.Name)). + To(WithTransform(ConditionStatus(batchv1.JobComplete), Equal(corev1.ConditionTrue))) +} diff --git a/tests/e2e/setup.sh b/tests/e2e/setup.sh new file mode 100755 index 000000000..d5c99cbf8 --- /dev/null +++ b/tests/e2e/setup.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +# Copyright 2022 IBM, Red Hat +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -euo pipefail +: "${KUBERAY_VERSION}" + +echo Deploying KubeRay "${KUBERAY_VERSION}" +kubectl apply --server-side -k "github.com/ray-project/kuberay/ray-operator/config/default?ref=${KUBERAY_VERSION}&timeout=180s" + +cat < Date: Tue, 14 Nov 2023 17:45:59 +0000 Subject: [PATCH 02/10] Fix pre-commit and remove redundant files --- .github/workflows/e2e_tests.yaml | 2 +- tests/e2e/install-codeflare-sdk.sh | 2 +- tests/e2e/kind.sh | 129 ----------------------------- tests/e2e/mnist_raycluster_sdk.py | 6 +- 4 files changed, 5 insertions(+), 134 deletions(-) delete mode 100755 tests/e2e/kind.sh diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index 42463583e..24c22f655 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -27,7 +27,7 @@ concurrency: jobs: kubernetes: - runs-on: ubuntu-20.04-4core + runs-on: ubuntu-20.04 steps: - name: Cleanup diff --git a/tests/e2e/install-codeflare-sdk.sh b/tests/e2e/install-codeflare-sdk.sh index d7a1b2531..e30f7ca50 100644 --- a/tests/e2e/install-codeflare-sdk.sh +++ b/tests/e2e/install-codeflare-sdk.sh @@ -20,4 +20,4 @@ ls # poetry install --with test,docs # Return to the previous directory -# cd .. \ No newline at end of file +# cd .. diff --git a/tests/e2e/kind.sh b/tests/e2e/kind.sh deleted file mode 100755 index 0b936f990..000000000 --- a/tests/e2e/kind.sh +++ /dev/null @@ -1,129 +0,0 @@ -# #!/bin/bash - -# # Copyright 2022 IBM, Red Hat -# # -# # Licensed under the Apache License, Version 2.0 (the "License"); -# # you may not use this file except in compliance with the License. -# # You may obtain a copy of the License at -# # -# # http://www.apache.org/licenses/LICENSE-2.0 -# # -# # Unless required by applicable law or agreed to in writing, software -# # distributed under the License is distributed on an "AS IS" BASIS, -# # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# # See the License for the specific language governing permissions and -# # limitations under the License. -# set -euo pipefail -# : "${INGRESS_NGINX_VERSION:=controller-v1.6.4}" - -# echo "Creating KinD cluster" -# cat < Date: Tue, 14 Nov 2023 17:58:42 +0000 Subject: [PATCH 03/10] Fix Action --- .github/workflows/e2e_tests.yaml | 1 - Makefile | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index 24c22f655..6bfc1fe8c 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -85,7 +85,6 @@ jobs: echo Setting up CodeFlare stack make setup-e2e - make defaults manifests fmt vet cd .. diff --git a/Makefile b/Makefile index c0d41155d..6b1f2eaa9 100644 --- a/Makefile +++ b/Makefile @@ -383,4 +383,4 @@ verify-imports: openshift-goimports ## Run import verifications. .PHONY: scorecard-bundle scorecard-bundle: install-operator-sdk ## Run scorecard tests on bundle image. - $(OPERATOR_SDK) scorecard bundle \ No newline at end of file + $(OPERATOR_SDK) scorecard bundle From c5724bbd4710df59c0503393ad925eabd124070d Mon Sep 17 00:00:00 2001 From: ChristianZaccaria Date: Tue, 14 Nov 2023 18:24:16 +0000 Subject: [PATCH 04/10] Remove redundant files --- Dockerfile | 23 -- Makefile | 386 ------------------ .../codeflare_sdk-0.0.0.dev0-py3-none-any.whl | Bin 39252 -> 39456 bytes tests/e2e/mnist.py | 2 - tests/e2e/setup.sh | 58 --- tmp.yaml | 37 -- tmpclusterrole.yaml | 9 - tmpclusterrolebinding.yaml | 12 - tmpingressesrole.yaml | 8 - tmpingressesroleb.yaml | 12 - 10 files changed, 547 deletions(-) delete mode 100644 Dockerfile delete mode 100644 Makefile delete mode 100755 tests/e2e/setup.sh delete mode 100644 tmp.yaml delete mode 100644 tmpclusterrole.yaml delete mode 100644 tmpclusterrolebinding.yaml delete mode 100644 tmpingressesrole.yaml delete mode 100644 tmpingressesroleb.yaml diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 2ea7fead4..000000000 --- a/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# Build the manager binary -FROM registry.access.redhat.com/ubi8/go-toolset:1.19.10-10 as builder - -WORKDIR /workspace -# Copy the Go Modules manifests -COPY go.mod go.mod -COPY go.sum go.sum -RUN go mod download - -# Copy the go source -COPY main.go main.go -COPY pkg/ pkg/ - -# Build -USER root -RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -o manager main.go - -FROM registry.access.redhat.com/ubi8/ubi-minimal:8.7 -WORKDIR / -COPY --from=builder /workspace/manager . - -USER 65532:65532 -ENTRYPOINT ["/manager"] diff --git a/Makefile b/Makefile deleted file mode 100644 index 6b1f2eaa9..000000000 --- a/Makefile +++ /dev/null @@ -1,386 +0,0 @@ -# VERSION defines the project version for the bundle. -# Update this value when you upgrade the version of your project. -# To re-generate a bundle for another specific version without changing the standard setup, you can: -# - use the VERSION as arg of the bundle target (e.g make bundle VERSION=v0.0.2) -# - use environment variables to overwrite this value (e.g export VERSION=v0.0.2) -# best if we could detect this. If we cannot, we need to document it somewhere. -# then we can add a patch in the `PHONY: bundle` -# BUNDLE_VERSION is declared as bundle versioning doesn't use semver - -PREVIOUS_VERSION ?= v0.0.0-dev -VERSION ?= v0.0.0-dev -BUNDLE_VERSION ?= $(VERSION:v%=%) - -# INSTASCALE_VERSION defines the default version of the InstaScale controller -INSTASCALE_VERSION ?= v0.0.9 -INSTASCALE_REPO ?= github.com/project-codeflare/instascale - -# MCAD_VERSION defines the default version of the MCAD controller -MCAD_VERSION ?= 725a614debe3d34d1547c1659ef5ad49f8f6c5df -MCAD_REPO ?= github.com/project-codeflare/multi-cluster-app-dispatcher -# Upstream MCAD is currently only creating release tags of the form `vX.Y.Z` (i.e the version) -MCAD_CRD ?= ${MCAD_REPO}/config/crd?ref=${MCAD_VERSION} - -# KUBERAY_VERSION defines the default version of the KubeRay operator (used for testing) -KUBERAY_VERSION ?= v0.6.0 - -# RAY_VERSION defines the default version of Ray (used for testing) -RAY_VERSION ?= 2.5.0 - -# CODEFLARE_SDK_VERSION defines the default version of the CodeFlare SDK -CODEFLARE_SDK_VERSION ?= 0.8.0 - -# OPERATORS_REPO_ORG points to GitHub repository organization where bundle PR is opened against -# OPERATORS_REPO_FORK_ORG points to GitHub repository fork organization where bundle build is pushed to -OPERATORS_REPO_ORG ?= redhat-openshift-ecosystem -OPERATORS_REPO_FORK_ORG ?= project-codeflare - -# CHANNELS define the bundle channels used in the bundle. -# Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") -# To re-generate a bundle for other specific channels without changing the standard setup, you can: -# - use the CHANNELS as arg of the bundle target (e.g make bundle CHANNELS=candidate,fast,stable) -# - use environment variables to overwrite this value (e.g export CHANNELS="candidate,fast,stable") -ifneq ($(origin CHANNELS), undefined) -BUNDLE_CHANNELS := --channels=$(CHANNELS) -endif - -# DEFAULT_CHANNEL defines the default channel used in the bundle. -# Add a new line here if you would like to change its default config. (E.g DEFAULT_CHANNEL = "stable") -# To re-generate a bundle for any other default channel without changing the default setup, you can: -# - use the DEFAULT_CHANNEL as arg of the bundle target (e.g make bundle DEFAULT_CHANNEL=stable) -# - use environment variables to overwrite this value (e.g export DEFAULT_CHANNEL="stable") -ifneq ($(origin DEFAULT_CHANNEL), undefined) -BUNDLE_DEFAULT_CHANNEL := --default-channel=$(DEFAULT_CHANNEL) -endif -BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL) - -# IMAGE_ORG_BASE defines the base container registry and organization for container images. -IMAGE_ORG_BASE ?= quay.io/project-codeflare - -# IMAGE_TAG_BASE defines the docker.io namespace and part of the image name for remote images. -# This variable is used to construct full image tags for bundle and catalog images. -# -# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both -# codeflare.dev/codeflare-operator-bundle:$VERSION and codeflare.dev/codeflare-operator-catalog:$VERSION. -IMAGE_TAG_BASE ?= $(IMAGE_ORG_BASE)/codeflare-operator - -# RAY_IMAGE defines the default container image for Ray (used for testing) -RAY_IMAGE ?= rayproject/ray:$(RAY_VERSION) - -# BUNDLE_IMG defines the image:tag used for the bundle. -# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=/:) -BUNDLE_IMG ?= $(IMAGE_TAG_BASE)-bundle:$(VERSION) - -# BUNDLE_GEN_FLAGS are the flags passed to the operator-sdk generate bundle command -BUNDLE_GEN_FLAGS ?= -q --overwrite --version $(BUNDLE_VERSION) $(BUNDLE_METADATA_OPTS) - -# USE_IMAGE_DIGESTS defines if images are resolved via tags or digests -# You can enable this value if you would like to use SHA Based Digests -# To enable set flag to true -USE_IMAGE_DIGESTS ?= false -ifeq ($(USE_IMAGE_DIGESTS), true) - BUNDLE_GEN_FLAGS += --use-image-digests -endif - -# Image URL to use all building/pushing image targets -IMG ?= ${IMAGE_TAG_BASE}:${VERSION} -# ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. -ENVTEST_K8S_VERSION = 1.24.2 - -# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) -ifeq (,$(shell go env GOBIN)) -GOBIN=$(shell go env GOPATH)/bin -else -GOBIN=$(shell go env GOBIN) -endif - -# Setting SHELL to bash allows bash commands to be executed by recipes. -# Options are set to exit when a recipe line exits non-zero or a piped command fails. -SHELL = /usr/bin/env bash -o pipefail -.SHELLFLAGS = -ec - -.PHONY: all -all: build - -##@ General - -# The help target prints out all targets with their descriptions organized -# beneath their categories. The categories are represented by '##@' and the -# target descriptions by '##'. The awk commands is responsible for reading the -# entire set of makefiles included in this invocation, looking for lines of the -# file as xyz: ## something, and then pretty-format the target and help. Then, -# if there's a line with ##@ something, that gets pretty-printed as a category. -# More info on the usage of ANSI control characters for terminal formatting: -# https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters -# More info on the awk command: -# http://linuxcommand.org/lc3_adv_awk.php - -.PHONY: help -help: ## Display this help. - @awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - -##@ Development - -DEFAULTS_TEST_FILE := tests/support/defaults.go - -.PHONY: defaults -defaults: - $(info Regenerating $(DEFAULTS_TEST_FILE)) - @echo "package support" > $(DEFAULTS_TEST_FILE) - @echo "" >> $(DEFAULTS_TEST_FILE) - @echo "// ***********************" >> $(DEFAULTS_TEST_FILE) - @echo "// DO NOT EDIT THIS FILE" >> $(DEFAULTS_TEST_FILE) - @echo "// ***********************" >> $(DEFAULTS_TEST_FILE) - @echo "" >> $(DEFAULTS_TEST_FILE) - @echo "const (" >> $(DEFAULTS_TEST_FILE) - @echo " CodeFlareSDKVersion = \"$(CODEFLARE_SDK_VERSION)\"" >> $(DEFAULTS_TEST_FILE) - @echo " RayVersion = \"$(RAY_VERSION)\"" >> $(DEFAULTS_TEST_FILE) - @echo " RayImage = \"$(RAY_IMAGE)\"" >> $(DEFAULTS_TEST_FILE) - @echo "" >> $(DEFAULTS_TEST_FILE) - @echo ")" >> $(DEFAULTS_TEST_FILE) - @echo "" >> $(DEFAULTS_TEST_FILE) - - gofmt -w $(DEFAULTS_TEST_FILE) - -.PHONY: manifests -manifests: controller-gen ## Generate RBAC objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role webhook paths="./..." - -.PHONY: fmt -fmt: ## Run go fmt against code. - go fmt ./... - -.PHONY: vet -vet: ## Run go vet against code. - go vet ./... - - -##@ Build - -.PHONY: modules -modules: ## Update Go dependencies. - go get $(MCAD_REPO)@$(MCAD_VERSION) - go get $(INSTASCALE_REPO)@$(INSTASCALE_VERSION) - go get github.com/ray-project/kuberay/ray-operator - go mod tidy - -.PHONY: build -build: modules defaults fmt vet ## Build manager binary. - go build -o bin/manager main.go - -.PHONY: run -run: modules defaults manifests fmt vet ## Run a controller from your host. - go run ./main.go - -.PHONY: image-build -image-build: test-unit ## Build container image with the manager. - podman build -t ${IMG} . - -.PHONY: image-push -image-push: image-build ## Push container image with the manager. - podman push ${IMG} - -##@ Deployment - -ifndef ignore-not-found - ignore-not-found = false -endif - -.PHONY: install -install: manifests kustomize ## Install CRDs into the K8s cluster specified in ~/.kube/config. - $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml - $(KUSTOMIZE) build config/crd | kubectl apply -f - - git restore config/* - -.PHONY: uninstall -uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml - $(KUSTOMIZE) build config/crd | kubectl delete --ignore-not-found=$(ignore-not-found) -f - - git restore config/* - -.PHONY: deploy -deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config. - $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml - cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG} - $(KUSTOMIZE) build config/default | kubectl apply -f - - git restore config/* - -.PHONY: undeploy -undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion. - $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml - $(KUSTOMIZE) build config/default | kubectl delete --ignore-not-found=$(ignore-not-found) -f - - git restore config/* - -##@ Build Dependencies - -## Location to install dependencies to -LOCALBIN ?= $(shell pwd)/bin -$(LOCALBIN): - mkdir -p $(LOCALBIN) - -## Tool Binaries -KUSTOMIZE ?= $(LOCALBIN)/kustomize -CONTROLLER_GEN ?= $(LOCALBIN)/controller-gen -ENVTEST ?= $(LOCALBIN)/setup-envtest -OPENSHIFT-GOIMPORTS ?= $(LOCALBIN)/openshift-goimports -OPERATOR_SDK ?= $(LOCALBIN)/operator-sdk -GH_CLI ?= $(LOCALBIN)/gh -SED ?= /usr/bin/sed - -## Tool Versions -KUSTOMIZE_VERSION ?= v4.5.4 -CODEGEN_VERSION ?= v0.27.2 -CONTROLLER_TOOLS_VERSION ?= v0.9.2 -OPERATOR_SDK_VERSION ?= v1.27.0 -GH_CLI_VERSION ?= 2.30.0 - -KUSTOMIZE_INSTALL_SCRIPT ?= "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" -.PHONY: kustomize -kustomize: $(KUSTOMIZE) ## Download kustomize locally if necessary. -$(KUSTOMIZE): $(LOCALBIN) - test -s $(LOCALBIN)/kustomize || { curl -s $(KUSTOMIZE_INSTALL_SCRIPT) | bash -s -- $(subst v,,$(KUSTOMIZE_VERSION)) $(LOCALBIN); } - -GH_CLI_DL_URL := https://github.com/cli/cli/releases/download/v$(GH_CLI_VERSION) -GH_CLI_DL_FILENAME := gh_$(GH_CLI_VERSION)_$(shell go env GOOS)_$(shell go env GOARCH) -.PHONY: install-gh-cli -install-gh-cli: $(GH_CLI) -$(GH_CLI): $(LOCALBIN) - curl -L $(GH_CLI_DL_URL)/$(GH_CLI_DL_FILENAME).tar.gz --output $(GH_CLI_DL_FILENAME).tar.gz - tar -xvzf $(GH_CLI_DL_FILENAME).tar.gz - cp $(GH_CLI_DL_FILENAME)/bin/gh $(GH_CLI) - rm -rf $(GH_CLI_DL_FILENAME) - rm $(GH_CLI_DL_FILENAME).tar.gz - -.PHONY: controller-gen -controller-gen: $(CONTROLLER_GEN) ## Download controller-gen locally if necessary. -$(CONTROLLER_GEN): $(LOCALBIN) - test -s $(LOCALBIN)/controller-gen || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-tools/cmd/controller-gen@$(CONTROLLER_TOOLS_VERSION) - -.PHONY: envtest -envtest: $(ENVTEST) ## Download envtest-setup locally if necessary. -$(ENVTEST): $(LOCALBIN) - test -s $(LOCALBIN)/setup-envtest || GOBIN=$(LOCALBIN) go install sigs.k8s.io/controller-runtime/tools/setup-envtest@latest - -.PHONY: openshift-goimports -openshift-goimports: $(OPENSHIFT-GOIMPORTS) ## Download openshift-goimports locally if necessary. -$(OPENSHIFT-GOIMPORTS): $(LOCALBIN) - test -s $(LOCALBIN)/openshift-goimports || GOBIN=$(LOCALBIN) go install github.com/openshift-eng/openshift-goimports@latest - -OPERATOR_SDK_DL_URL := https://github.com/operator-framework/operator-sdk/releases/download/$(OPERATOR_SDK_VERSION) -.PHONY: install-operator-sdk -install-operator-sdk: $(OPERATOR_SDK) ## Download fixed version operator-sdk binary for consist outcome -$(OPERATOR_SDK): $(LOCALBIN) - curl -L $(OPERATOR_SDK_DL_URL)/operator-sdk_$(shell go env GOOS)_$(shell go env GOARCH) --output $(LOCALBIN)/operator-sdk - chmod +x $(OPERATOR_SDK) - -.PHONY: validate-bundle -validate-bundle: install-operator-sdk - $(OPERATOR_SDK) bundle validate ./bundle --select-optional suite=operatorframework - -.PHONY: bundle -bundle: defaults manifests kustomize install-operator-sdk ## Generate bundle manifests and metadata, then validate generated files. - $(OPERATOR_SDK) generate kustomize manifests -q - $(SED) -i -E "s|(- )\${MCAD_REPO}.*|\1\${MCAD_CRD}|" config/crd/mcad/kustomization.yaml - cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) - cd config/manifests && $(KUSTOMIZE) edit add patch --patch '[{"op":"add", "path":"/metadata/annotations/containerImage", "value": "$(IMG)" }]' --kind ClusterServiceVersion - cd config/manifests && $(KUSTOMIZE) edit add patch --patch '[{"op":"add", "path":"/spec/replaces", "value": "codeflare-operator.$(PREVIOUS_VERSION)" }]' --kind ClusterServiceVersion - $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) - $(MAKE) validate-bundle - git restore config/* - -.PHONY: bundle-build -bundle-build: bundle ## Build the bundle image. - podman build -f bundle.Dockerfile -t $(BUNDLE_IMG) . - -.PHONY: bundle-push -bundle-push: ## Push the bundle image. - podman push $(BUNDLE_IMG) $(BUNDLE_PUSH_OPT) - -.PHONY: openshift-community-operator-release -openshift-community-operator-release: install-gh-cli bundle ## build bundle and create PR in OpenShift community operators repository - git clone https://x-access-token:$(GH_TOKEN)@github.com/$(OPERATORS_REPO_FORK_ORG)/community-operators-prod.git - cd community-operators-prod && git remote add upstream https://github.com/$(OPERATORS_REPO_ORG)/community-operators-prod.git && git pull upstream main && git push origin main - cp -r bundle community-operators-prod/operators/codeflare-operator/$(BUNDLE_VERSION) - cd community-operators-prod && git checkout -b codeflare-release-$(BUNDLE_VERSION) && git add operators/codeflare-operator/$(BUNDLE_VERSION)/* && git commit -m "add bundle manifests codeflare version $(BUNDLE_VERSION)" --signoff && git push origin codeflare-release-$(BUNDLE_VERSION) - gh pr create --repo $(OPERATORS_REPO_ORG)/community-operators-prod --title "CodeFlare $(BUNDLE_VERSION)" --body "New release of codeflare operator" --head $(OPERATORS_REPO_FORK_ORG):codeflare-release-$(BUNDLE_VERSION) --base main - rm -rf community-operators-prod - -.PHONY: opm -OPM = ./bin/opm -opm: ## Download opm locally if necessary. -ifeq (,$(wildcard $(OPM))) -ifeq (,$(shell which opm 2>/dev/null)) - @{ \ - set -e ;\ - mkdir -p $(dir $(OPM)) ;\ - OS=$(shell go env GOOS) && ARCH=$(shell go env GOARCH) && \ - curl -sSLo $(OPM) https://github.com/operator-framework/operator-registry/releases/download/v1.23.0/$${OS}-$${ARCH}-opm ;\ - chmod +x $(OPM) ;\ - } -else -OPM = $(shell which opm) -endif -endif - -# A comma-separated list of bundle images (e.g. make catalog-build BUNDLE_IMGS=example.com/operator-bundle:v0.1.0,example.com/operator-bundle:v0.2.0). -# These images MUST exist in a registry and be pull-able. -BUNDLE_IMGS ?= $(BUNDLE_IMG) - -# The image tag given to the resulting catalog image (e.g. make catalog-build CATALOG_IMG=example.com/operator-catalog:v0.2.0). -CATALOG_IMG ?= $(IMAGE_TAG_BASE)-catalog:$(VERSION) - -# Set CATALOG_BASE_IMG to an existing catalog image tag to add $BUNDLE_IMGS to that image. -ifneq ($(origin CATALOG_BASE_IMG), undefined) -FROM_INDEX_OPT := --from-index $(CATALOG_BASE_IMG) -endif - -# Build a catalog image by adding bundle images to an empty catalog using the operator package manager tool, 'opm'. -# This recipe invokes 'opm' in 'semver' bundle add mode. For more information on add modes, see: -# https://github.com/operator-framework/community-operators/blob/7f1438c/docs/packaging-operator.md#updating-your-existing-operator -.PHONY: catalog-build -catalog-build: opm ## Build a catalog image. - $(OPM) index add --container-tool podman --mode semver --tag $(CATALOG_IMG) --bundles $(BUNDLE_IMGS) $(FROM_INDEX_OPT) - -# Build a catalog image by adding bundle images to existing catalog using the operator package manager tool, 'opm'. -.PHONY: catalog-build-from-index -catalog-build-from-index: opm ## Build a catalog image. - mkdir catalog - $(OPM) render $(CATALOG_BASE_IMG) -o yaml > catalog/bundles.yaml - $(OPM) render $(BUNDLE_IMG) $(OPM_BUNDLE_OPT) > catalog/codeflare-operator-bundle.yaml - $(SED) -i -E "s/(.*)(- name: codeflare-operator.$(PREVIOUS_VERSION).*)/\1- name: codeflare-operator.$(VERSION)\n replaces: codeflare-operator.$(PREVIOUS_VERSION)\n\2/" catalog/bundles.yaml - $(OPM) validate catalog - $(OPM) generate dockerfile catalog - podman build . -f catalog.Dockerfile -t $(CATALOG_IMG) - -# Push the catalog image. -.PHONY: catalog-push -catalog-push: ## Push a catalog image. - podman push $(CATALOG_IMG) $(CATALOG_PUSH_OPT) - -.PHONY: test-unit -test-unit: defaults manifests fmt vet envtest ## Run unit tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --bin-dir $(LOCALBIN) -p path)" go test $(go list ./... | grep -v /test/) -coverprofile cover.out - -.PHONY: test-e2e -test-e2e: ## Run e2e tests. - go test -timeout 30m -v ./tests/e2e -run TestMNISTRayClusterSDK - -.PHONY: kind-e2e -kind-e2e: ## Set up e2e KinD cluster. - tests/e2e/kind.sh - -.PHONY: setup-e2e -setup-e2e: ## Set up e2e tests. - KUBERAY_VERSION=$(KUBERAY_VERSION) tests/e2e/setup.sh - -.PHONY: imports -imports: openshift-goimports ## Organize imports in go files using openshift-goimports. Example: make imports - $(OPENSHIFT-GOIMPORTS) - -.PHONY: verify-imports -verify-imports: openshift-goimports ## Run import verifications. - ./hack/verify-imports.sh $(OPENSHIFT-GOIMPORTS) - -.PHONY: scorecard-bundle -scorecard-bundle: install-operator-sdk ## Run scorecard tests on bundle image. - $(OPERATOR_SDK) scorecard bundle diff --git a/tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl b/tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl index da85a840077f75398ff1b2a1d190bdf882c681e1..872bc4edb183aaa421edc093759008693ddbb814 100644 GIT binary patch delta 14320 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�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 delta 14094 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 diff --git a/tests/e2e/mnist.py b/tests/e2e/mnist.py index 244c84d29..a99589659 100644 --- a/tests/e2e/mnist.py +++ b/tests/e2e/mnist.py @@ -35,7 +35,6 @@ class LitMNIST(LightningModule): def __init__(self, data_dir=PATH_DATASETS, hidden_size=64, learning_rate=2e-4): - super().__init__() # Set our init args as class attributes @@ -116,7 +115,6 @@ def prepare_data(self): MNIST(self.data_dir, train=False, download=True) def setup(self, stage=None): - # Assign train/val datasets for use in dataloaders if stage == "fit" or stage is None: mnist_full = MNIST(self.data_dir, train=True, transform=self.transform) diff --git a/tests/e2e/setup.sh b/tests/e2e/setup.sh deleted file mode 100755 index d5c99cbf8..000000000 --- a/tests/e2e/setup.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/bash - -# Copyright 2022 IBM, Red Hat -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -set -euo pipefail -: "${KUBERAY_VERSION}" - -echo Deploying KubeRay "${KUBERAY_VERSION}" -kubectl apply --server-side -k "github.com/ray-project/kuberay/ray-operator/config/default?ref=${KUBERAY_VERSION}&timeout=180s" - -cat < Date: Wed, 22 Nov 2023 19:57:54 +0000 Subject: [PATCH 05/10] Reflect Poetry changes --- .github/workflows/e2e_tests.yaml | 2 +- copyscript.sh | 30 +++++++++++ tests/e2e/install-codeflare-sdk.sh | 50 ++++++++++++------ tests/e2e/mnist_raycluster_sdk.py | 2 +- tests/e2e/mnist_raycluster_sdk_test.go | 73 ++++++++++++++++++-------- 5 files changed, 116 insertions(+), 41 deletions(-) create mode 100755 copyscript.sh diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index 6bfc1fe8c..983fed4ae 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -92,7 +92,7 @@ jobs: run: | export CODEFLARE_TEST_TIMEOUT_SHORT=1m export CODEFLARE_TEST_TIMEOUT_MEDIUM=5m - export CODEFLARE_TEST_TIMEOUT_LONG=10m + export CODEFLARE_TEST_TIMEOUT_LONG=15m export CODEFLARE_TEST_OUTPUT_DIR=${{ env.TEMP_DIR }} echo "CODEFLARE_TEST_OUTPUT_DIR=${CODEFLARE_TEST_OUTPUT_DIR}" >> $GITHUB_ENV diff --git a/copyscript.sh b/copyscript.sh new file mode 100755 index 000000000..cfbf30b90 --- /dev/null +++ b/copyscript.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# command to be ran on local host and not in the pod +# kubectl apply -f temp-pod.yaml +# kubectl cp ./ default/temp-pod4:/mnt + + + +echo "starting" +namespace=$1 +# podname=$(kubectl get pods -n "${namespace}" -o custom-columns=:metadata.name | grep "^sdk") +# kubectl cp ./ ${namespace}/${podname}:/codeflare-sdk + +# kubectl cp ./ ${namespace}/temp-pod:/mnt + +sleep 60 + +# Get the name of the pod starting with 'sdk' and its status +read podname podstatus <<< $(kubectl get pods -n "${namespace}" -o custom-columns=:metadata.name,:status.phase | grep "^sdk" | awk '{print $1, $2}') + +echo "$podname, $podstatus, $namespace" + +# Check if the pod is found and is in 'Running' status +if [[ -n "$podname" && "$podstatus" == "Running" ]]; then + echo "Pod ${podname} is running. Proceeding to copy files." + kubectl cp ../.././ "${namespace}/${podname}:/codeflare-sdk" +else + echo "Pod not found or not running." + exit 1 +fi diff --git a/tests/e2e/install-codeflare-sdk.sh b/tests/e2e/install-codeflare-sdk.sh index e30f7ca50..0c574d4a0 100644 --- a/tests/e2e/install-codeflare-sdk.sh +++ b/tests/e2e/install-codeflare-sdk.sh @@ -1,23 +1,39 @@ #!/bin/bash +# Generate zip file beforehand +# tar -czvf root-dir.tar.gz --exclude='.git' --exclude='.github' --exclude='.pytest_cache' ./ + +# Create temp-pod to contain the zip file +# kubectl apply -f temp-pod.yaml + +# Copy the zip file to the temp-pod:/mnt +# kubectl cp root-dir.tar.gz temp-pod:/mnt + +# Run a shell in the temp-pod +# kubectl exec -it temp-pod -- /bin/sh + +# Unzip the zip file +# tar -xzvf /mnt/root-dir.tar.gz -C /mnt + +# Not necessary as the PVC is mounted to /codeflare-sdk +# mv /mnt/* /codeflare-sdk/ + +## Copy files from temp-pod /mnt into the codeflare-sdk volume mount in this other pod. +# kubectl cp default/temp-pod:/mnt codeflare-sdk + + +cd .. + # Install Poetry and configure virtualenvs pip install poetry poetry config virtualenvs.create false -# Clone the CodeFlare SDK repository -echo "first ls" -ls -pip uninstall codeflare-sdk -echo "install codeflare sdk" -pip install codeflare_sdk-0.0.0.dev0-py3-none-any.whl -echo "second ls" -ls -# git clone --branch main https://github.com/project-codeflare/codeflare-sdk.git -# cd codeflare-sdk - -# # Lock dependencies and install them -# poetry lock --no-update -# poetry install --with test,docs - -# Return to the previous directory -# cd .. +cd codeflare-sdk + +# Lock dependencies and install them +poetry lock --no-update +poetry install --with test,docs + +# Return to the workdir +cd .. +cd workdir diff --git a/tests/e2e/mnist_raycluster_sdk.py b/tests/e2e/mnist_raycluster_sdk.py index acfac7204..067993a3b 100644 --- a/tests/e2e/mnist_raycluster_sdk.py +++ b/tests/e2e/mnist_raycluster_sdk.py @@ -67,7 +67,7 @@ done = False time = 0 -timeout = 300 +timeout = 500 while not done: status = job.status() if is_terminal(status.state): diff --git a/tests/e2e/mnist_raycluster_sdk_test.go b/tests/e2e/mnist_raycluster_sdk_test.go index cf4080aea..e60492421 100644 --- a/tests/e2e/mnist_raycluster_sdk_test.go +++ b/tests/e2e/mnist_raycluster_sdk_test.go @@ -17,6 +17,8 @@ limitations under the License. package e2e import ( + "bytes" + "os/exec" "testing" . "github.com/onsi/gomega" @@ -51,8 +53,6 @@ func TestMNISTRayClusterSDK(t *testing.T) { "requirements.txt": ReadFile(test, "mnist_pip_requirements.txt"), // MNIST training script "mnist.py": ReadFile(test, "mnist.py"), - // SDK Wheel File - "codeflare_sdk-0.0.0.dev0-py3-none-any.whl": ReadWhlFile(test, "codeflare_sdk-0.0.0.dev0-py3-none-any.whl"), // codeflare-sdk installation script "install-codeflare-sdk.sh": ReadFile(test, "install-codeflare-sdk.sh"), }) @@ -113,6 +113,30 @@ func TestMNISTRayClusterSDK(t *testing.T) { BackoffLimit: Ptr(int32(0)), Template: corev1.PodTemplateSpec{ Spec: corev1.PodSpec{ + Volumes: []corev1.Volume{ + { + Name: "test", + VolumeSource: corev1.VolumeSource{ + ConfigMap: &corev1.ConfigMapVolumeSource{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: config.Name, + }, + }, + }, + }, + { + Name: "codeflare-sdk", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + { + Name: "workdir", + VolumeSource: corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }, + }, + }, Containers: []corev1.Container{ { Name: "test", @@ -123,13 +147,20 @@ func TestMNISTRayClusterSDK(t *testing.T) { {Name: "PYTHONUSERBASE", Value: "/workdir"}, {Name: "RAY_IMAGE", Value: GetRayImage()}, }, - Command: []string{"/bin/sh", "-c", "cp /test/* . && chmod +x install-codeflare-sdk.sh && ./install-codeflare-sdk.sh && python mnist_raycluster_sdk.py" + " " + namespace.Name}, - // Command: []string{"/bin/sh", "-c", "pip install /test/codeflare_sdk-0.0.0.dev0-py3-none-any.whl && cp /test/* . && python mnist_raycluster_sdk.py" + " " + namespace.Name}, + Command: []string{ + "/bin/sh", "-c", + "while [ ! -f /codeflare-sdk/pyproject.toml ]; do sleep 1; done; " + + "cp /test/* . && chmod +x install-codeflare-sdk.sh && ./install-codeflare-sdk.sh && python mnist_raycluster_sdk.py " + namespace.Name, + }, VolumeMounts: []corev1.VolumeMount{ { Name: "test", MountPath: "/test", }, + { + Name: "codeflare-sdk", + MountPath: "/codeflare-sdk", + }, { Name: "workdir", MountPath: "/workdir", @@ -148,24 +179,6 @@ func TestMNISTRayClusterSDK(t *testing.T) { }, }, }, - Volumes: []corev1.Volume{ - { - Name: "test", - VolumeSource: corev1.VolumeSource{ - ConfigMap: &corev1.ConfigMapVolumeSource{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: config.Name, - }, - }, - }, - }, - { - Name: "workdir", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, - }, - }, - }, RestartPolicy: corev1.RestartPolicyNever, ServiceAccountName: sa.Name, }, @@ -194,6 +207,22 @@ func TestMNISTRayClusterSDK(t *testing.T) { test.Expect(err).NotTo(HaveOccurred()) test.T().Logf("Created Job %s/%s successfully", job.Namespace, job.Name) + go func() { + scriptName := "../.././copyscript.sh" + cmd := exec.Command(scriptName, namespace.Name) + + var stdoutBuf, stderrBuf bytes.Buffer + cmd.Stdout = &stdoutBuf + cmd.Stderr = &stderrBuf + + // Run the script + if err := cmd.Run(); err != nil { + t.Logf("STDOUT: %s", stdoutBuf.String()) + t.Logf("STDERR: %s", stderrBuf.String()) + t.Logf("Failed to run the script: %v", err) + } + }() + test.T().Logf("Waiting for Job %s/%s to complete", job.Namespace, job.Name) test.Eventually(Job(test, job.Namespace, job.Name), TestTimeoutLong).Should( Or( From cea789e1d56482d4687b1d415a8d1acc9c84d62d Mon Sep 17 00:00:00 2001 From: ChristianZaccaria Date: Fri, 24 Nov 2023 10:23:05 +0000 Subject: [PATCH 06/10] Cleanup code --- .github/workflows/e2e_tests.yaml | 2 -- copyscript.sh | 30 -------------------------- tests/e2e/install-codeflare-sdk.sh | 22 ------------------- tests/e2e/mnist_raycluster_sdk.py | 3 +-- tests/e2e/mnist_raycluster_sdk_test.go | 4 ++-- tests/e2e/sdk-to-pod.sh | 18 ++++++++++++++++ tests/e2e/support.go | 9 -------- 7 files changed, 21 insertions(+), 67 deletions(-) delete mode 100755 copyscript.sh create mode 100755 tests/e2e/sdk-to-pod.sh diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index 983fed4ae..0f1aeeedc 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -35,7 +35,6 @@ jobs: ls -lart echo "Initial status:" df -h - echo "Cleaning up resources:" sudo swapoff -a sudo rm -f /swapfile @@ -45,7 +44,6 @@ jobs: sudo rm -rf "/usr/local/share/boost" sudo rm -rf "$AGENT_TOOLSDIRECTORY" docker rmi $(docker image ls -aq) - echo "Final status:" df -h diff --git a/copyscript.sh b/copyscript.sh deleted file mode 100755 index cfbf30b90..000000000 --- a/copyscript.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash - -# command to be ran on local host and not in the pod -# kubectl apply -f temp-pod.yaml -# kubectl cp ./ default/temp-pod4:/mnt - - - -echo "starting" -namespace=$1 -# podname=$(kubectl get pods -n "${namespace}" -o custom-columns=:metadata.name | grep "^sdk") -# kubectl cp ./ ${namespace}/${podname}:/codeflare-sdk - -# kubectl cp ./ ${namespace}/temp-pod:/mnt - -sleep 60 - -# Get the name of the pod starting with 'sdk' and its status -read podname podstatus <<< $(kubectl get pods -n "${namespace}" -o custom-columns=:metadata.name,:status.phase | grep "^sdk" | awk '{print $1, $2}') - -echo "$podname, $podstatus, $namespace" - -# Check if the pod is found and is in 'Running' status -if [[ -n "$podname" && "$podstatus" == "Running" ]]; then - echo "Pod ${podname} is running. Proceeding to copy files." - kubectl cp ../.././ "${namespace}/${podname}:/codeflare-sdk" -else - echo "Pod not found or not running." - exit 1 -fi diff --git a/tests/e2e/install-codeflare-sdk.sh b/tests/e2e/install-codeflare-sdk.sh index 0c574d4a0..e78085824 100644 --- a/tests/e2e/install-codeflare-sdk.sh +++ b/tests/e2e/install-codeflare-sdk.sh @@ -1,27 +1,5 @@ #!/bin/bash -# Generate zip file beforehand -# tar -czvf root-dir.tar.gz --exclude='.git' --exclude='.github' --exclude='.pytest_cache' ./ - -# Create temp-pod to contain the zip file -# kubectl apply -f temp-pod.yaml - -# Copy the zip file to the temp-pod:/mnt -# kubectl cp root-dir.tar.gz temp-pod:/mnt - -# Run a shell in the temp-pod -# kubectl exec -it temp-pod -- /bin/sh - -# Unzip the zip file -# tar -xzvf /mnt/root-dir.tar.gz -C /mnt - -# Not necessary as the PVC is mounted to /codeflare-sdk -# mv /mnt/* /codeflare-sdk/ - -## Copy files from temp-pod /mnt into the codeflare-sdk volume mount in this other pod. -# kubectl cp default/temp-pod:/mnt codeflare-sdk - - cd .. # Install Poetry and configure virtualenvs diff --git a/tests/e2e/mnist_raycluster_sdk.py b/tests/e2e/mnist_raycluster_sdk.py index 067993a3b..d46c6e4c5 100644 --- a/tests/e2e/mnist_raycluster_sdk.py +++ b/tests/e2e/mnist_raycluster_sdk.py @@ -62,12 +62,11 @@ script="mnist.py", scheduler_args={"requirements": "requirements.txt"}, ) -print("Submitting Job OSAOUBDAUDDAOUBDOUBUBAD") job = jobdef.submit(cluster) done = False time = 0 -timeout = 500 +timeout = 900 while not done: status = job.status() if is_terminal(status.state): diff --git a/tests/e2e/mnist_raycluster_sdk_test.go b/tests/e2e/mnist_raycluster_sdk_test.go index e60492421..baaeb8937 100644 --- a/tests/e2e/mnist_raycluster_sdk_test.go +++ b/tests/e2e/mnist_raycluster_sdk_test.go @@ -208,14 +208,14 @@ func TestMNISTRayClusterSDK(t *testing.T) { test.T().Logf("Created Job %s/%s successfully", job.Namespace, job.Name) go func() { - scriptName := "../.././copyscript.sh" + scriptName := "./sdk-to-pod.sh" cmd := exec.Command(scriptName, namespace.Name) var stdoutBuf, stderrBuf bytes.Buffer cmd.Stdout = &stdoutBuf cmd.Stderr = &stderrBuf - // Run the script + // Run the script to copy the SDK to the pod if err := cmd.Run(); err != nil { t.Logf("STDOUT: %s", stdoutBuf.String()) t.Logf("STDERR: %s", stderrBuf.String()) diff --git a/tests/e2e/sdk-to-pod.sh b/tests/e2e/sdk-to-pod.sh new file mode 100755 index 000000000..7001b88f4 --- /dev/null +++ b/tests/e2e/sdk-to-pod.sh @@ -0,0 +1,18 @@ +#!/bin/bash +echo "Starting the script to copy the SDK to the pod" +namespace=$1 + +# Get the name of the pod starting with 'sdk' and its status +while : ; do + read podname podstatus <<< $(kubectl get pods -n "${namespace}" -o custom-columns=:metadata.name,:status.phase | grep "^sdk" | awk '{print $1, $2}') + echo "$podname, $podstatus, $namespace" + # Check if the pod is found and is in 'Running' status + if [[ -n "$podname" && "$podstatus" == "Running" ]]; then + echo "Pod ${podname} is running. Proceeding to copy files." + kubectl cp ../.././ "${namespace}/${podname}:/codeflare-sdk" + break + else + echo "Waiting for pod to be in Running state in namespace ${namespace}..." + sleep 5 + fi +done diff --git a/tests/e2e/support.go b/tests/e2e/support.go index 547ed32cd..cc55beebd 100644 --- a/tests/e2e/support.go +++ b/tests/e2e/support.go @@ -19,8 +19,6 @@ package e2e import ( "embed" - "io/ioutil" - "github.com/onsi/gomega" "github.com/project-codeflare/codeflare-common/support" @@ -35,10 +33,3 @@ func ReadFile(t support.Test, fileName string) []byte { t.Expect(err).NotTo(gomega.HaveOccurred()) return file } - -func ReadWhlFile(t support.Test, fileName string) []byte { - t.T().Helper() - file, err := ioutil.ReadFile(fileName) - t.Expect(err).NotTo(gomega.HaveOccurred()) - return file -} From 467048a7e22a6e6327a1f804abe583a78897aff7 Mon Sep 17 00:00:00 2001 From: ChristianZaccaria Date: Fri, 15 Dec 2023 15:28:45 +0000 Subject: [PATCH 07/10] Use common workflow to setup and start KinD --- .github/actions/kind/action.yml | 74 ------------------ .github/resources-kind/kind.yaml | 31 -------- .github/workflows/e2e_tests.yaml | 9 ++- .../codeflare_sdk-0.0.0.dev0-py3-none-any.whl | Bin 39456 -> 0 bytes 4 files changed, 8 insertions(+), 106 deletions(-) delete mode 100644 .github/actions/kind/action.yml delete mode 100644 .github/resources-kind/kind.yaml delete mode 100644 tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl diff --git a/.github/actions/kind/action.yml b/.github/actions/kind/action.yml deleted file mode 100644 index f76e60af5..000000000 --- a/.github/actions/kind/action.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: "Set up KinD" -description: "Step to start and configure KinD cluster" - -inputs: - kind-node-hostname: - description: "Hostname of the main kind node" - required: false - default: kind - -runs: - using: "composite" - steps: - - name: Init directories - shell: bash - run: | - TEMP_DIR="$(pwd)/tmp" - mkdir -p "${TEMP_DIR}" - echo "TEMP_DIR=${TEMP_DIR}" >> $GITHUB_ENV - - mkdir -p "$(pwd)/bin" - echo "$(pwd)/bin" >> $GITHUB_PATH - - - name: Container image registry - shell: bash - run: | - podman run -d -p 5000:5000 --name registry registry:2.8.1 - - export REGISTRY_ADDRESS=$(hostname -i):5000 - echo "REGISTRY_ADDRESS=${REGISTRY_ADDRESS}" >> $GITHUB_ENV - echo "Container image registry started at ${REGISTRY_ADDRESS}" - - KIND_CONFIG_FILE=${{ env.TEMP_DIR }}/kind.yaml - echo "KIND_CONFIG_FILE=${KIND_CONFIG_FILE}" >> $GITHUB_ENV - envsubst < .github/resources-kind/kind.yaml > ${KIND_CONFIG_FILE} - - sudo --preserve-env=REGISTRY_ADDRESS sh -c 'cat > /etc/containers/registries.conf.d/local.conf <> $GITHUB_ENV - echo "CLUSTER_HOSTNAME=${{ inputs.kind-node-hostname }}" >> $GITHUB_ENV diff --git a/.github/resources-kind/kind.yaml b/.github/resources-kind/kind.yaml deleted file mode 100644 index 4546589b8..000000000 --- a/.github/resources-kind/kind.yaml +++ /dev/null @@ -1,31 +0,0 @@ -# --------------------------------------------------------------------------- -# Copyright 2023. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# --------------------------------------------------------------------------- - -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -nodes: - - role: control-plane - image: kindest/node:v1.25.3@sha256:f52781bc0d7a19fb6c405c2af83abfeb311f130707a0e219175677e366cc45d1 - kubeadmConfigPatches: - - | - kind: InitConfiguration - nodeRegistration: - kubeletExtraArgs: - node-labels: "ingress-ready=true" -containerdConfigPatches: - - |- - [plugins."io.containerd.grpc.v1.cri".registry.mirrors."${REGISTRY_ADDRESS}"] - endpoint = ["http://${REGISTRY_ADDRESS}"] diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index 0f1aeeedc..c2da71c85 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -52,6 +52,13 @@ jobs: with: submodules: recursive + - name: Checkout common repo code + uses: actions/checkout@v3 + with: + repository: 'project-codeflare/codeflare-common' + ref: 'main' + path: 'common' + - name: Checkout CodeFlare operator repository uses: actions/checkout@v3 with: @@ -69,7 +76,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup and start KinD cluster - uses: ./.github/actions/kind + uses: ./common/github-actions/kind - name: Deploy CodeFlare stack id: deploy diff --git a/tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl b/tests/e2e/codeflare_sdk-0.0.0.dev0-py3-none-any.whl deleted file mode 100644 index 872bc4edb183aaa421edc093759008693ddbb814..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39456 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 From 8095624ccf0697647969183b7aab60693c598f41 Mon Sep 17 00:00:00 2001 From: ChristianZaccaria Date: Wed, 3 Jan 2024 11:05:23 +0000 Subject: [PATCH 08/10] Use cp package directly --- go.mod | 30 +++++++++- go.sum | 67 +++++++++++++++++++++++ tests/e2e/mnist_raycluster_sdk_test.go | 64 ++++++++++++---------- tests/e2e/sdk-to-pod.sh | 18 ------ tests/e2e/support.go | 76 ++++++++++++++++++++++++++ 5 files changed, 207 insertions(+), 48 deletions(-) delete mode 100755 tests/e2e/sdk-to-pod.sh diff --git a/go.mod b/go.mod index 76ca0575e..6bb665dc9 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,26 @@ require ( github.com/ray-project/kuberay/ray-operator v1.0.0 k8s.io/api v0.26.3 k8s.io/apimachinery v0.26.3 + k8s.io/cli-runtime v0.26.3 + k8s.io/client-go v0.26.3 + k8s.io/kubectl v0.26.3 ) require ( + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.1.3 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/chai2010/gettext-go v1.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful/v3 v3.10.1 // indirect + github.com/evanphx/json-patch v4.12.0+incompatible // indirect + github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect + github.com/fatih/camelcase v1.0.0 // indirect + github.com/fvbommel/sortorder v1.0.1 // indirect + github.com/go-errors/errors v1.0.1 // indirect github.com/go-logr/logr v1.2.4 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/jsonreference v0.20.1 // indirect @@ -26,28 +37,43 @@ require ( github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/glog v1.0.0 // indirect github.com/golang/protobuf v1.5.3 // indirect + github.com/google/btree v1.0.1 // indirect github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gorilla/css v1.0.0 // indirect + github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect github.com/imdario/mergo v0.3.12 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect github.com/microcosm-cc/bluemonday v1.0.18 // indirect + github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/moby/spdystream v0.2.0 // indirect + github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openshift-online/ocm-sdk-go v0.1.368 // indirect github.com/openshift/api v0.0.0-20230213134911-7ba313770556 // indirect github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c // indirect + github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect github.com/prometheus/common v0.37.0 // indirect github.com/prometheus/procfs v0.8.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect + github.com/spf13/cobra v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/xlab/treeprint v1.1.0 // indirect + go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect golang.org/x/net v0.17.0 // indirect golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sys v0.13.0 // indirect @@ -59,12 +85,14 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/client-go v0.26.3 // indirect + k8s.io/component-base v0.26.3 // indirect k8s.io/klog/v2 v2.100.1 // indirect k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect k8s.io/utils v0.0.0-20230505201702-9f6742963106 // indirect sigs.k8s.io/controller-runtime v0.14.6 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/kustomize/api v0.12.1 // indirect + sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index c9b425cb8..d85b8eb71 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,12 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= 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/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -41,6 +45,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= @@ -55,6 +60,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= 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= @@ -65,12 +72,16 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= 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/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= 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/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/emicklei/go-restful/v3 v3.10.1 h1:rc42Y5YTp7Am7CS630D7JmhRjq4UlEUuEKfrDac4bSQ= github.com/emicklei/go-restful/v3 v3.10.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -80,12 +91,21 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM= +github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4= +github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0= 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/fvbommel/sortorder v1.0.1 h1:dSnXLt4mJYH25uDDGa3biZNQsozaUWDSWeKJ0qqFfzE= +github.com/fvbommel/sortorder v1.0.1/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= 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= @@ -148,6 +168,8 @@ 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/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/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0= github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -176,6 +198,8 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/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= @@ -183,6 +207,9 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 h1:pdN6V1QBWetyv/0+wjACpqVH+eVULgEjkurDLq3goeM= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= 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= @@ -191,6 +218,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1: github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/itchyny/gojq v0.12.7 h1:hYPTpeWfrJ1OT+2j6cvBScbhl0TkdwGM4bc66onUSOQ= github.com/itchyny/gojq v0.12.7/go.mod h1:ZdvNHVlzPgUf8pgjnuDTmGfHA/21KoutQUJ3An/xNuw= github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU= @@ -276,6 +305,8 @@ github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.5/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= @@ -290,6 +321,12 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09 github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/microcosm-cc/bluemonday v1.0.18 h1:6HcxvXDAi3ARt3slx6nTesbvorIc3QeTzBNRvWktHBo= github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM= +github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae h1:O4SWKdcHVCvYqyDV+9CJA1fcDN2L11Bule0iFy3YlAI= +github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -297,6 +334,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 h1:n6/2gBQ3RWajuToeY6ZtZTIKv2v7ThUy5KKusIT0yc0= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -322,6 +361,8 @@ github.com/openshift/api v0.0.0-20230213134911-7ba313770556 h1:7W2fOhJicyEff24Va github.com/openshift/api v0.0.0-20230213134911-7ba313770556/go.mod h1:aQ6LDasvHMvHZXqLHnX2GRmnfTWCF/iIwz8EMTTIE9A= github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c h1:CV76yFOTXmq9VciBR3Bve5ZWzSxdft7gaMVB3kS0rwg= github.com/openshift/client-go v0.0.0-20221019143426-16aed247da5c/go.mod h1:lFMO8mLHXWFzSdYvGNo8ivF9SfF6zInA8ZGw4phRnUE= +github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= 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 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -365,7 +406,10 @@ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= @@ -373,6 +417,9 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB 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/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= @@ -380,6 +427,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ 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 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -393,6 +441,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ 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 v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= +github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= 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= @@ -405,6 +455,8 @@ 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.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 h1:+FNtrFTmVw0YZGpBGX56XDee331t6JAXeK2bcyhLOOc= +go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5/go.mod h1:nmDLcffg48OtT/PSW0Hg7FvpRQsQh5OSqIylirxKC7o= 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= @@ -544,6 +596,7 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191002063906-3421d5a6bb1c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/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= @@ -575,6 +628,7 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -616,6 +670,7 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn 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-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-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -771,6 +826,8 @@ gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C 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= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= 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= @@ -782,12 +839,18 @@ k8s.io/api v0.26.3 h1:emf74GIQMTik01Aum9dPP0gAypL8JTLl/lHa4V9RFSU= k8s.io/api v0.26.3/go.mod h1:PXsqwPMXBSBcL1lJ9CYDKy7kIReUydukS5JiRlxC3qE= k8s.io/apimachinery v0.26.3 h1:dQx6PNETJ7nODU3XPtrwkfuubs6w7sX0M8n61zHIV/k= k8s.io/apimachinery v0.26.3/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I= +k8s.io/cli-runtime v0.26.3 h1:3ULe0oI28xmgeLMVXIstB+ZL5CTGvWSMVMLeHxitIuc= +k8s.io/cli-runtime v0.26.3/go.mod h1:5YEhXLV4kLt/OSy9yQwtSSNZU2Z7aTEYta1A+Jg4VC4= k8s.io/client-go v0.26.3 h1:k1UY+KXfkxV2ScEL3gilKcF7761xkYsSD6BC9szIu8s= k8s.io/client-go v0.26.3/go.mod h1:ZPNu9lm8/dbRIPAgteN30RSXea6vrCpFvq+MateTUuQ= +k8s.io/component-base v0.26.3 h1:oC0WMK/ggcbGDTkdcqefI4wIZRYdK3JySx9/HADpV0g= +k8s.io/component-base v0.26.3/go.mod h1:5kj1kZYwSC6ZstHJN7oHBqcJC6yyn41eR+Sqa/mQc8E= k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg= k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg= +k8s.io/kubectl v0.26.3 h1:bZ5SgFyeEXw6XTc1Qji0iNdtqAC76lmeIIQULg2wNXM= +k8s.io/kubectl v0.26.3/go.mod h1:02+gv7Qn4dupzN3fi/9OvqqdW+uG/4Zi56vc4Zmsp1g= k8s.io/utils v0.0.0-20230505201702-9f6742963106 h1:EObNQ3TW2D+WptiYXlApGNLVy0zm/JIBVY9i+M4wpAU= k8s.io/utils v0.0.0-20230505201702-9f6742963106/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= @@ -797,6 +860,10 @@ sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92 sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/kustomize/api v0.12.1 h1:7YM7gW3kYBwtKvoY216ZzY+8hM+lV53LUayghNRJ0vM= +sigs.k8s.io/kustomize/api v0.12.1/go.mod h1:y3JUhimkZkR6sbLNwfJHxvo1TCLwuwm14sCYnkH6S1s= +sigs.k8s.io/kustomize/kyaml v0.13.9 h1:Qz53EAaFFANyNgyOEJbT/yoIHygK40/ZcvU3rgry2Tk= +sigs.k8s.io/kustomize/kyaml v0.13.9/go.mod h1:QsRbD0/KcU+wdk0/L0fIp2KLnohkVzs6fQ85/nOXac4= sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE= sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E= sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= diff --git a/tests/e2e/mnist_raycluster_sdk_test.go b/tests/e2e/mnist_raycluster_sdk_test.go index baaeb8937..9d4dc862f 100644 --- a/tests/e2e/mnist_raycluster_sdk_test.go +++ b/tests/e2e/mnist_raycluster_sdk_test.go @@ -17,9 +17,9 @@ limitations under the License. package e2e import ( - "bytes" - "os/exec" + "strings" "testing" + "time" . "github.com/onsi/gomega" . "github.com/project-codeflare/codeflare-common/support" @@ -81,22 +81,9 @@ func TestMNISTRayClusterSDK(t *testing.T) { }, } - // Create cluster wide RBAC, required for SDK OpenShift check - // TODO reevaluate once SDK change OpenShift detection logic - clusterPolicyRules := []rbacv1.PolicyRule{ - { - Verbs: []string{"get", "list"}, - APIGroups: []string{"config.openshift.io"}, - Resources: []string{"ingresses"}, - ResourceNames: []string{"cluster"}, - }, - } - sa := CreateServiceAccount(test, namespace.Name) role := CreateRole(test, namespace.Name, policyRules) CreateRoleBinding(test, namespace.Name, sa, role) - clusterRole := CreateClusterRole(test, clusterPolicyRules) - CreateClusterRoleBinding(test, sa, clusterRole) job := &batchv1.Job{ TypeMeta: metav1.TypeMeta{ @@ -208,20 +195,39 @@ func TestMNISTRayClusterSDK(t *testing.T) { test.T().Logf("Created Job %s/%s successfully", job.Namespace, job.Name) go func() { - scriptName := "./sdk-to-pod.sh" - cmd := exec.Command(scriptName, namespace.Name) - - var stdoutBuf, stderrBuf bytes.Buffer - cmd.Stdout = &stdoutBuf - cmd.Stderr = &stderrBuf - - // Run the script to copy the SDK to the pod - if err := cmd.Run(); err != nil { - t.Logf("STDOUT: %s", stdoutBuf.String()) - t.Logf("STDERR: %s", stderrBuf.String()) - t.Logf("Failed to run the script: %v", err) - } - }() + // Checking if pod is found and running + podName := "" + foundPod := false + for !foundPod { + pods, _ := test.Client().Core().CoreV1().Pods(namespace.Name).List(test.Ctx(), metav1.ListOptions{ + LabelSelector: "job-name=sdk", + }) + for _, pod := range pods.Items { + if strings.HasPrefix(pod.Name, "sdk-") && pod.Status.Phase == corev1.PodRunning { + podName = pod.Name + foundPod = true + test.T().Logf("Pod is running!") + break + } + } + if !foundPod { + test.T().Logf("Waiting for pod to start...") + time.Sleep(5 * time.Second) + } + } + + // Get rest config + restConfig, err := GetRestConfig(test); if err != nil { + test.T().Errorf("Error getting rest config: %v", err) + } + + // Copy codeflare-sdk to the pod + srcDir := "../.././" + dstDir := "/codeflare-sdk" + if err := CopyToPod(test, namespace.Name, podName, restConfig, srcDir, dstDir); err != nil { + test.T().Errorf("Error copying codeflare-sdk to pod: %v", err) + } + }() test.T().Logf("Waiting for Job %s/%s to complete", job.Namespace, job.Name) test.Eventually(Job(test, job.Namespace, job.Name), TestTimeoutLong).Should( diff --git a/tests/e2e/sdk-to-pod.sh b/tests/e2e/sdk-to-pod.sh deleted file mode 100755 index 7001b88f4..000000000 --- a/tests/e2e/sdk-to-pod.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -echo "Starting the script to copy the SDK to the pod" -namespace=$1 - -# Get the name of the pod starting with 'sdk' and its status -while : ; do - read podname podstatus <<< $(kubectl get pods -n "${namespace}" -o custom-columns=:metadata.name,:status.phase | grep "^sdk" | awk '{print $1, $2}') - echo "$podname, $podstatus, $namespace" - # Check if the pod is found and is in 'Running' status - if [[ -n "$podname" && "$podstatus" == "Running" ]]; then - echo "Pod ${podname} is running. Proceeding to copy files." - kubectl cp ../.././ "${namespace}/${podname}:/codeflare-sdk" - break - else - echo "Waiting for pod to be in Running state in namespace ${namespace}..." - sleep 5 - fi -done diff --git a/tests/e2e/support.go b/tests/e2e/support.go index cc55beebd..9ef8e1769 100644 --- a/tests/e2e/support.go +++ b/tests/e2e/support.go @@ -18,8 +18,21 @@ package e2e import ( "embed" + "os" + "path/filepath" "github.com/onsi/gomega" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/runtime/serializer" + "k8s.io/cli-runtime/pkg/genericclioptions" + "k8s.io/client-go/discovery" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + "k8s.io/kubectl/pkg/cmd/cp" + "k8s.io/kubectl/pkg/cmd/util" + "k8s.io/kubectl/pkg/scheme" "github.com/project-codeflare/codeflare-common/support" ) @@ -33,3 +46,66 @@ func ReadFile(t support.Test, fileName string) []byte { t.Expect(err).NotTo(gomega.HaveOccurred()) return file } + +func GetRestConfig(t support.Test) (*rest.Config, error) { + const GroupName = "" + var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} + kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config") + restConfig, err := clientcmd.BuildConfigFromFlags("", kubeconfig) + if err != nil { + t.T().Errorf("Error building kubeconfig: %v", err) + return restConfig, err + } + restConfig.APIPath = "/api" + restConfig.GroupVersion = &SchemeGroupVersion + restConfig.NegotiatedSerializer = serializer.WithoutConversionCodecFactory{CodecFactory: scheme.Codecs} + return restConfig, nil +} + +func CopyToPod(t support.Test, namespace string, podName string, restConfig *rest.Config, srcDir string, dstDir string) error { + ioStreams, _, _, _ := genericclioptions.NewTestIOStreams() + copyOptions := cp.NewCopyOptions(ioStreams) + factory := util.NewFactory(newRestClientGetter(namespace, restConfig)) + if err := copyOptions.Complete(factory, cp.NewCmdCp(factory, ioStreams), []string{srcDir, podName + ":" + dstDir}); err != nil { + t.T().Errorf("error when completing all the required options: %v", err) + return err + } + if err := copyOptions.Validate(); err != nil { + t.T().Errorf("error when validating the provided values for CopyOptions: %v", err) + return err + } + if err := copyOptions.Run(); err != nil { + t.T().Errorf("could not run copy operation: %v", err) + return err + } + return nil +} + +// restClientGetter interface is used to get a rest client from a kubeconfig +type restClientGetter struct { + ClientConfig *rest.Config + ConfigLoader clientcmd.ClientConfig +} + +func newRestClientGetter(namespace string, clientConfig *rest.Config) restClientGetter { + return restClientGetter{ + ClientConfig: clientConfig, + ConfigLoader: clientcmd.NewDefaultClientConfig(clientcmdapi.Config{}, &clientcmd.ConfigOverrides{Context: clientcmdapi.Context{Namespace: namespace}}), + } +} + +func (r restClientGetter) ToRESTConfig() (*rest.Config, error) { + return r.ClientConfig, nil +} + +func (r restClientGetter) ToRawKubeConfigLoader() clientcmd.ClientConfig { + return r.ConfigLoader +} + +func (r restClientGetter) ToDiscoveryClient() (discovery.CachedDiscoveryInterface, error) { + return nil, nil +} + +func (r restClientGetter) ToRESTMapper() (meta.RESTMapper, error) { + return nil, nil +} From 79925e3512dcae5e199ab104038ee4966f672480 Mon Sep 17 00:00:00 2001 From: ChristianZaccaria Date: Wed, 3 Jan 2024 11:16:45 +0000 Subject: [PATCH 09/10] Upgrade to go1.20 --- .github/workflows/e2e_tests.yaml | 2 +- go.mod | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index c2da71c85..51b01ba18 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -68,7 +68,7 @@ jobs: - name: Set Go uses: actions/setup-go@v3 with: - go-version: v1.19 + go-version: v1.20 - name: Set up gotestfmt uses: gotesttools/gotestfmt-action@v2 diff --git a/go.mod b/go.mod index 6bb665dc9..08f9e6514 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/project-codeflare/codeflare-sdk -go 1.19 +go 1.20 require ( github.com/onsi/gomega v1.27.10 From 60c8ac644dac5357e44a5df37bda20fe36894c1e Mon Sep 17 00:00:00 2001 From: ChristianZaccaria Date: Thu, 4 Jan 2024 09:42:24 +0000 Subject: [PATCH 10/10] Address requested changes --- .github/workflows/e2e_tests.yaml | 6 ++++++ src/codeflare_sdk/templates/base-template.yaml | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/.github/workflows/e2e_tests.yaml b/.github/workflows/e2e_tests.yaml index 51b01ba18..a89f5c21a 100644 --- a/.github/workflows/e2e_tests.yaml +++ b/.github/workflows/e2e_tests.yaml @@ -117,6 +117,12 @@ jobs: echo "Printing KubeRay operator logs" kubectl logs -n ray-system --tail -1 -l app.kubernetes.io/name=kuberay | tee ${CODEFLARE_TEST_OUTPUT_DIR}/kuberay.log + - name: Export all KinD pod logs + uses: ./common/github-actions/kind-export-logs + if: always() && steps.deploy.outcome == 'success' + with: + output-directory: ${CODEFLARE_TEST_OUTPUT_DIR} + - name: Upload logs uses: actions/upload-artifact@v3 if: always() && steps.deploy.outcome == 'success' diff --git a/src/codeflare_sdk/templates/base-template.yaml b/src/codeflare_sdk/templates/base-template.yaml index 8f4575a05..8e6fd0e9e 100644 --- a/src/codeflare_sdk/templates/base-template.yaml +++ b/src/codeflare_sdk/templates/base-template.yaml @@ -16,21 +16,21 @@ spec: custompodresources: - replicas: 1 requests: - cpu: 1 - memory: 4G + cpu: 2 + memory: 8G nvidia.com/gpu: 0 limits: - cpu: 1 - memory: 4G + cpu: 2 + memory: 8G nvidia.com/gpu: 0 - replicas: 3 requests: - cpu: 1 - memory: 4G + cpu: 2 + memory: 12G nvidia.com/gpu: 1 limits: - cpu: 1 - memory: 4G + cpu: 2 + memory: 12G nvidia.com/gpu: 1 generictemplate: # This config demonstrates KubeRay's Ray autoscaler integration.