mirror of
https://github.com/googleforgames/open-match.git
synced 2025-03-25 13:24:18 +00:00
@ -12,3 +12,4 @@
|
||||
# below:
|
||||
.git
|
||||
.gitignore
|
||||
#!include:.gitignore
|
||||
|
25
.gitignore
vendored
25
.gitignore
vendored
@ -25,7 +25,7 @@
|
||||
populations
|
||||
|
||||
# local config files
|
||||
*.json
|
||||
#*.json
|
||||
|
||||
# Discarded code snippets
|
||||
build.sh
|
||||
@ -67,3 +67,26 @@ msbuild.wrn
|
||||
|
||||
# Visual Studio 2015
|
||||
.vs/
|
||||
|
||||
# Goland
|
||||
.idea/
|
||||
|
||||
# Nodejs files placed when building Hugo, ok to allow if we actually start using Nodejs.
|
||||
package.json
|
||||
package-lock.json
|
||||
|
||||
site/resources/_gen/
|
||||
|
||||
# Node Modules
|
||||
node_modules/
|
||||
|
||||
# Compiled Binaries
|
||||
cmd/backendapi/backendapi
|
||||
cmd/frontendapi/frontendapi
|
||||
cmd/mmforc/mmforc
|
||||
cmd/mmlogicapi/mmlogicapi
|
||||
examples/backendclient/backendclient
|
||||
examples/evaluators/golang/simple/simple
|
||||
examples/functions/golang/manual-simple/manual-simple
|
||||
test/cmd/clientloadgen/clientloadgen
|
||||
test/cmd/frontendclient/frontendclient
|
||||
|
@ -1,5 +1,12 @@
|
||||
# Release history
|
||||
|
||||
## v0.4.0 (alpha)
|
||||
|
||||
### Release notes
|
||||
- Thanks to completion of Issues [#42](issues/42) and [#45](issues/45), there is no longer a need to use the `openmatch-base` image when building components of Open Match. Each stand alone appliation now is self-contained in its `Dockerfile` and `cloudbuild.yaml` files, and builds have been substantially simplified. **Note**: The default `Dockerfile` and `cloudbuild.yaml` now tag their images with the version number, not `dev`, and the YAML files in the `install` directory now reflect this.
|
||||
- This paves the way for CI/CD in an upcoming version.
|
||||
- This paves the way for public images in an upcoming version!
|
||||
|
||||
## v0.3.0 (alpha)
|
||||
This update is focused on the Frontend API and Player Records, including more robust code for indexing, deindexing, reading, writing, and expiring player requests from Open Match state storage. All Frontend API function argument have changed, although many only slightly. Please join the [Slack channel](https://open-match.slack.com/) if you need help ([Signup link](https://join.slack.com/t/open-match/shared_invite/enQtNDM1NjcxNTY4MTgzLWQzMzE1MGY5YmYyYWY3ZjE2MjNjZTdmYmQ1ZTQzMmNiNGViYmQyN2M4ZmVkMDY2YzZlOTUwMTYwMzI1Y2I2MjU))!
|
||||
|
||||
|
@ -2,6 +2,8 @@
|
||||
FROM golang:1.10.3 as builder
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match
|
||||
COPY config config
|
||||
RUN rm -f config/matchmaker_config.json
|
||||
RUN rm -f config/matchmaker_config.yaml
|
||||
COPY internal internal
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/internal
|
||||
RUN go get -d -v ...
|
||||
|
7
Dockerfile.base-build
Normal file
7
Dockerfile.base-build
Normal file
@ -0,0 +1,7 @@
|
||||
FROM golang:1.12
|
||||
ENV GO111MODULE=on
|
||||
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match
|
||||
COPY . .
|
||||
RUN go mod download
|
||||
|
524
Makefile
Normal file
524
Makefile
Normal file
@ -0,0 +1,524 @@
|
||||
################################################################################
|
||||
## Open Match Makefile ##
|
||||
################################################################################
|
||||
|
||||
# Notice: There's 2 variables you need to make sure are set.
|
||||
# GCP_PROJECT_ID if you're working against GCP.
|
||||
# Or $REGISTRY if you want to use your own custom docker registry.
|
||||
|
||||
# Basic Deployment
|
||||
# make create-gke-cluster OR make create-mini-cluster
|
||||
# make push-helm
|
||||
# make REGISTRY=gcr.io/$PROJECT_ID push-images -j$(nproc)
|
||||
# make install-chart
|
||||
#
|
||||
# Generate Files
|
||||
# make all-protos
|
||||
#
|
||||
# Building
|
||||
# make all -j$(nproc)
|
||||
#
|
||||
# Access monitoring
|
||||
# make proxy-prometheus
|
||||
# make proxy-grafana
|
||||
#
|
||||
# Run those tools
|
||||
# make run-backendclient
|
||||
# make run-frontendclient
|
||||
# make run-clientloadgen
|
||||
#
|
||||
# Teardown
|
||||
# make delete-mini-cluster
|
||||
# make delete-gke-cluster
|
||||
#
|
||||
## http://makefiletutorial.com/
|
||||
|
||||
BASE_VERSION = 0.4.0
|
||||
VERSION_SUFFIX = $(shell git rev-parse --short=7 HEAD)
|
||||
VERSION ?= $(BASE_VERSION)-$(VERSION_SUFFIX)
|
||||
|
||||
PROTOC_VERSION = 3.7.0
|
||||
GOLANG_VERSION = 1.12
|
||||
HELM_VERSION = 2.13.0
|
||||
HUGO_VERSION = 0.54.0
|
||||
KUBECTL_VERSION = 1.13.0
|
||||
PROTOC_RELEASE_BASE = https://github.com/protocolbuffers/protobuf/releases/download/v$(PROTOC_VERSION)/protoc-$(PROTOC_VERSION)
|
||||
GO = go
|
||||
GO_BIN := $(GOPATH)/bin
|
||||
GO_BUILD_COMMAND = CGO_ENABLED=0 GOOS=linux $(GO) build -a -installsuffix cgo .
|
||||
BUILD_DIR = $(CURDIR)/build
|
||||
TOOLCHAIN_DIR = $(BUILD_DIR)/toolchain
|
||||
TOOLCHAIN_BIN = $(TOOLCHAIN_DIR)/bin
|
||||
PROTOC := $(TOOLCHAIN_BIN)/protoc
|
||||
PROTOC_INCLUDES := $(TOOLCHAIN_DIR)/include/
|
||||
GCP_PROJECT_ID =
|
||||
GCP_PROJECT_FLAG = --project=$(GCP_PROJECT_ID)
|
||||
OM_SITE_GCP_PROJECT_ID = open-match-site
|
||||
OM_SITE_GCP_PROJECT_FLAG = --project=$(OM_SITE_GCP_PROJECT_ID)
|
||||
REGISTRY = gcr.io/$(GCP_PROJECT_ID)
|
||||
TAG := $(VERSION)
|
||||
ALTERNATE_TAG := dev
|
||||
GKE_CLUSTER_NAME = om-cluster
|
||||
GCP_REGION = us-west1
|
||||
GCP_ZONE = us-west1-a
|
||||
EXE_EXTENSION =
|
||||
LOCAL_CLOUD_BUILD_PUSH = # --push
|
||||
GOPATH_PRIMARY = $(HOME)
|
||||
KUBECTL_RUN_ENV = --env='REDIS_SERVICE_HOST=$$(OPEN_MATCH_REDIS_MASTER_SERVICE_HOST)' --env='REDIS_SERVICE_PORT=$$(OPEN_MATCH_REDIS_MASTER_SERVICE_PORT)'
|
||||
GCP_LOCATION_FLAG = --zone $(GCP_ZONE)
|
||||
GO111MODULE = on
|
||||
PROMETHEUS_PORT = 9090
|
||||
GRAFANA_PORT = 3000
|
||||
SITE_PORT = 8080
|
||||
HELM = $(TOOLCHAIN_BIN)/helm
|
||||
TILLER = $(TOOLCHAIN_BIN)/tiller
|
||||
MINIKUBE = $(TOOLCHAIN_BIN)/minikube
|
||||
KUBECTL = $(TOOLCHAIN_BIN)/kubectl
|
||||
SERVICE = default
|
||||
|
||||
## Make port forwards accessible outside of the proxy machine.
|
||||
PORT_FORWARD_ADDRESS_FLAG = --address 0.0.0.0
|
||||
DASHBOARD_PORT = 9092
|
||||
export PATH := $(CURDIR)/node_modules/.bin/:$(TOOLCHAIN_BIN):$(TOOLCHAIN_DIR)/nodejs/bin:$(PATH)
|
||||
|
||||
ifneq (,$(wildcard $(TOOLCHAIN_GOLANG_DIR)/bin/go))
|
||||
export GO = $(CURDIR)/$(TOOLCHAIN_GOLANG_DIR)/bin/go
|
||||
export GOROOT = $(CURDIR)/$(TOOLCHAIN_GOLANG_DIR)
|
||||
export PATH := $(TOOLCHAIN_GOLANG_DIR):$(PATH)
|
||||
endif
|
||||
|
||||
# Get the project from gcloud if it's not set.
|
||||
ifeq ($(GCP_PROJECT_ID),)
|
||||
export GCP_PROJECT_ID = $(shell gcloud config list --format 'value(core.project)')
|
||||
endif
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
# TODO: Windows packages are here but things are broken since many paths are Linux based and zip vs tar.gz.
|
||||
HELM_PACKAGE = https://storage.googleapis.com/kubernetes-helm/helm-v$(HELM_VERSION)-windows-amd64.zip
|
||||
MINIKUBE_PACKAGE = https://storage.googleapis.com/minikube/releases/latest/minikube-windows-amd64.exe
|
||||
SKAFFOLD_PACKAGE = https://storage.googleapis.com/skaffold/releases/latest/skaffold-windows-amd64.exe
|
||||
EXE_EXTENSION = .exe
|
||||
PROTOC_PACKAGE = $(PROTOC_RELEASE_BASE)-win64.zip
|
||||
GO_PACKAGE = https://storage.googleapis.com/golang/go$(GOLANG_VERSION).windows-amd64.zip
|
||||
KUBECTL_PACKAGE = https://storage.googleapis.com/kubernetes-release/release/v$(KUBECTL_VERSION)/bin/windows/amd64/kubectl.exe
|
||||
HUGO_PACKAGE = https://github.com/gohugoio/hugo/releases/download/v$(HUGO_VERSION)/hugo_extended_$(HUGO_VERSION)_Windows-64bit.zip
|
||||
NODEJS_PACKAGE = https://nodejs.org/dist/v10.15.3/node-v10.15.3-win-x64.zip
|
||||
NODEJS_PACKAGE_NAME = nodejs.zip
|
||||
else
|
||||
UNAME_S := $(shell uname -s)
|
||||
ifeq ($(UNAME_S),Linux)
|
||||
HELM_PACKAGE = https://storage.googleapis.com/kubernetes-helm/helm-v$(HELM_VERSION)-linux-amd64.tar.gz
|
||||
MINIKUBE_PACKAGE = https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
|
||||
SKAFFOLD_PACKAGE = https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64
|
||||
PROTOC_PACKAGE = $(PROTOC_RELEASE_BASE)-linux-x86_64.zip
|
||||
GO_PACKAGE = https://storage.googleapis.com/golang/go$(GOLANG_VERSION).linux-amd64.tar.gz
|
||||
KUBECTL_PACKAGE = https://storage.googleapis.com/kubernetes-release/release/v$(KUBECTL_VERSION)/bin/linux/amd64/kubectl
|
||||
HUGO_PACKAGE = https://github.com/gohugoio/hugo/releases/download/v$(HUGO_VERSION)/hugo_extended_$(HUGO_VERSION)_Linux-64bit.tar.gz
|
||||
NODEJS_PACKAGE = https://nodejs.org/dist/v10.15.3/node-v10.15.3-linux-x64.tar.xz
|
||||
NODEJS_PACKAGE_NAME = nodejs.tar.xz
|
||||
endif
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
HELM_PACKAGE = https://storage.googleapis.com/kubernetes-helm/helm-v$(HELM_VERSION)-darwin-amd64.tar.gz
|
||||
MINIKUBE_PACKAGE = https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64
|
||||
SKAFFOLD_PACKAGE = https://storage.googleapis.com/skaffold/releases/latest/skaffold-darwin-amd64
|
||||
PROTOC_PACKAGE = $(PROTOC_RELEASE_BASE)-osx-x86_64.zip
|
||||
GO_PACKAGE = https://storage.googleapis.com/golang/go$(GOLANG_VERSION).darwin-amd64.tar.gz
|
||||
KUBECTL_PACKAGE = https://storage.googleapis.com/kubernetes-release/release/v$(KUBECTL_VERSION)/bin/darwin/amd64/kubectl
|
||||
HUGO_PACKAGE = https://github.com/gohugoio/hugo/releases/download/v$(HUGO_VERSION)/hugo_extended_$(HUGO_VERSION)_macOS-64bit.tar.gz
|
||||
NODEJS_PACKAGE = https://nodejs.org/dist/v10.15.3/node-v10.15.3-darwin-x64.tar.gz
|
||||
NODEJS_PACKAGE_NAME = nodejs.tar.gz
|
||||
endif
|
||||
endif
|
||||
|
||||
help:
|
||||
@cat Makefile | grep ^\# | grep -v ^\#\# | cut -c 3-
|
||||
|
||||
local-cloud-build:
|
||||
cloud-build-local --config=cloudbuild.yaml --dryrun=false $(LOCAL_CLOUD_BUILD_PUSH) -substitutions SHORT_SHA=$(VERSION_SUFFIX) .
|
||||
|
||||
push-images: push-service-images push-client-images push-mmf-example-images push-evaluator-example-images
|
||||
push-service-images: push-frontendapi-image push-backendapi-image push-mmforc-image push-mmlogicapi-image
|
||||
push-mmf-example-images: push-mmf-cs-mmlogic-simple-image push-mmf-go-mmlogic-simple-image push-mmf-php-mmlogic-simple-image push-mmf-py3-mmlogic-simple-image
|
||||
push-client-images: push-backendclient-image push-clientloadgen-image push-frontendclient-image
|
||||
push-evaluator-example-images: push-evaluator-simple-image
|
||||
|
||||
push-frontendapi-image: build-frontendapi-image
|
||||
docker push $(REGISTRY)/openmatch-frontendapi:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-frontendapi:$(ALTERNATE_TAG)
|
||||
|
||||
push-backendapi-image: build-backendapi-image
|
||||
docker push $(REGISTRY)/openmatch-backendapi:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-backendapi:$(ALTERNATE_TAG)
|
||||
|
||||
push-mmforc-image: build-mmforc-image
|
||||
docker push $(REGISTRY)/openmatch-mmforc:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-mmforc:$(ALTERNATE_TAG)
|
||||
|
||||
push-mmlogicapi-image: build-mmlogicapi-image
|
||||
docker push $(REGISTRY)/openmatch-mmlogicapi:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-mmlogicapi:$(ALTERNATE_TAG)
|
||||
|
||||
push-mmf-cs-mmlogic-simple-image: build-mmf-cs-mmlogic-simple-image
|
||||
docker push $(REGISTRY)/openmatch-mmf-cs-mmlogic-simple:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-mmf-cs-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
|
||||
push-mmf-go-mmlogic-simple-image: build-mmf-go-mmlogic-simple-image
|
||||
docker push $(REGISTRY)/openmatch-mmf-go-mmlogic-simple:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-mmf-go-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
|
||||
push-mmf-php-mmlogic-simple-image: build-mmf-php-mmlogic-simple-image
|
||||
docker push $(REGISTRY)/openmatch-mmf-php-mmlogic-simple:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-mmf-php-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
|
||||
push-mmf-py3-mmlogic-simple-image: build-mmf-py3-mmlogic-simple-image
|
||||
docker push $(REGISTRY)/openmatch-mmf-py3-mmlogic-simple:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-mmf-py3-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
|
||||
push-backendclient-image: build-backendclient-image
|
||||
docker push $(REGISTRY)/openmatch-backendclient:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-backendclient:$(ALTERNATE_TAG)
|
||||
|
||||
push-clientloadgen-image: build-clientloadgen-image
|
||||
docker push $(REGISTRY)/openmatch-clientloadgen:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-clientloadgen:$(ALTERNATE_TAG)
|
||||
|
||||
push-frontendclient-image: build-frontendclient-image
|
||||
docker push $(REGISTRY)/openmatch-frontendclient:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-frontendclient:$(ALTERNATE_TAG)
|
||||
|
||||
push-evaluator-simple-image: build-evaluator-simple-image
|
||||
docker push $(REGISTRY)/openmatch-evaluator-simple:$(TAG)
|
||||
docker push $(REGISTRY)/openmatch-evaluator-simple:$(ALTERNATE_TAG)
|
||||
|
||||
build-images: build-service-images build-client-images build-mmf-example-images build-evaluator-example-images
|
||||
build-service-images: build-frontendapi-image build-backendapi-image build-mmforc-image build-mmlogicapi-image
|
||||
build-client-images: build-backendclient-image build-clientloadgen-image build-frontendclient-image
|
||||
build-mmf-example-images: build-mmf-cs-mmlogic-simple-image build-mmf-go-mmlogic-simple-image build-mmf-php-mmlogic-simple-image build-mmf-py3-mmlogic-simple-image
|
||||
build-evaluator-example-images: build-evaluator-simple-image
|
||||
|
||||
build-frontendapi-image: cmd/frontendapi/frontendapi
|
||||
docker build -f cmd/frontendapi/Dockerfile -t $(REGISTRY)/openmatch-frontendapi:$(TAG) -t $(REGISTRY)/openmatch-frontendapi:$(ALTERNATE_TAG) .
|
||||
|
||||
build-backendapi-image: cmd/backendapi/backendapi
|
||||
docker build -f cmd/backendapi/Dockerfile -t $(REGISTRY)/openmatch-backendapi:$(TAG) -t $(REGISTRY)/openmatch-backendapi:$(ALTERNATE_TAG) .
|
||||
|
||||
build-mmforc-image: cmd/mmforc/mmforc
|
||||
docker build -f cmd/mmforc/Dockerfile -t $(REGISTRY)/openmatch-mmforc:$(TAG) -t $(REGISTRY)/openmatch-mmforc:$(ALTERNATE_TAG) .
|
||||
|
||||
build-mmlogicapi-image: cmd/mmlogicapi/mmlogicapi
|
||||
docker build -f cmd/mmlogicapi/Dockerfile -t $(REGISTRY)/openmatch-mmlogicapi:$(TAG) -t $(REGISTRY)/openmatch-mmlogicapi:$(ALTERNATE_TAG) .
|
||||
|
||||
build-mmf-cs-mmlogic-simple-image:
|
||||
cd examples/functions/csharp/simple/ && docker build -f Dockerfile -t $(REGISTRY)/openmatch-mmf-cs-mmlogic-simple:$(TAG) -t $(REGISTRY)/openmatch-mmf-cs-mmlogic-simple:$(ALTERNATE_TAG) .
|
||||
|
||||
build-mmf-go-mmlogic-simple-image:
|
||||
docker build -f examples/functions/golang/manual-simple/Dockerfile -t $(REGISTRY)/openmatch-mmf-go-mmlogic-simple:$(TAG) -t $(REGISTRY)/openmatch-mmf-go-mmlogic-simple:$(ALTERNATE_TAG) .
|
||||
|
||||
build-mmf-php-mmlogic-simple-image:
|
||||
docker build -f examples/functions/php/mmlogic-simple/Dockerfile -t $(REGISTRY)/openmatch-mmf-php-mmlogic-simple:$(TAG) -t $(REGISTRY)/openmatch-mmf-php-mmlogic-simple:$(ALTERNATE_TAG) .
|
||||
|
||||
build-mmf-py3-mmlogic-simple-image:
|
||||
docker build -f examples/functions/python3/mmlogic-simple/Dockerfile -t $(REGISTRY)/openmatch-mmf-py3-mmlogic-simple:$(TAG) -t $(REGISTRY)/openmatch-mmf-py3-mmlogic-simple:$(ALTERNATE_TAG) .
|
||||
|
||||
build-backendclient-image: examples/backendclient/backendclient
|
||||
docker build -f examples/backendclient/Dockerfile -t $(REGISTRY)/openmatch-backendclient:$(TAG) -t $(REGISTRY)/openmatch-backendclient:$(ALTERNATE_TAG) .
|
||||
|
||||
build-clientloadgen-image: test/cmd/clientloadgen/clientloadgen
|
||||
docker build -f test/cmd/clientloadgen/Dockerfile -t $(REGISTRY)/openmatch-clientloadgen:$(TAG) -t $(REGISTRY)/openmatch-clientloadgen:$(ALTERNATE_TAG) .
|
||||
|
||||
build-frontendclient-image: test/cmd/frontendclient/frontendclient
|
||||
docker build -f test/cmd/frontendclient/Dockerfile -t $(REGISTRY)/openmatch-frontendclient:$(TAG) -t $(REGISTRY)/openmatch-frontendclient:$(ALTERNATE_TAG) .
|
||||
|
||||
build-evaluator-simple-image: examples/evaluators/golang/simple/simple
|
||||
docker build -f examples/evaluators/golang/simple/Dockerfile -t $(REGISTRY)/openmatch-evaluator-simple:$(TAG) -t $(REGISTRY)/openmatch-evaluator-simple:$(ALTERNATE_TAG) .
|
||||
|
||||
clean-images:
|
||||
-docker rmi -f $(REGISTRY)/openmatch-frontendapi:$(TAG) $(REGISTRY)/openmatch-frontendapi:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-backendapi:$(TAG) $(REGISTRY)/openmatch-backendapi:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-mmforc:$(TAG) $(REGISTRY)/openmatch-mmforc:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-mmlogicapi:$(TAG) $(REGISTRY)/openmatch-mmlogicapi:$(ALTERNATE_TAG)
|
||||
|
||||
-docker rmi -f $(REGISTRY)/openmatch-mmf-cs-mmlogic-simple:$(TAG) $(REGISTRY)/openmatch-mmf-cs-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-mmf-go-mmlogic-simple:$(TAG) $(REGISTRY)/openmatch-mmf-go-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-mmf-php-mmlogic-simple:$(TAG) $(REGISTRY)/openmatch-mmf-php-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-mmf-py3-mmlogic-simple:$(TAG) $(REGISTRY)/openmatch-mmf-py3-mmlogic-simple:$(ALTERNATE_TAG)
|
||||
|
||||
-docker rmi -f $(REGISTRY)/openmatch-backendclient:$(TAG) $(REGISTRY)/openmatch-backendclient:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-clientloadgen:$(TAG) $(REGISTRY)/openmatch-clientloadgen:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-frontendclient:$(TAG) $(REGISTRY)/openmatch-frontendclient:$(ALTERNATE_TAG)
|
||||
-docker rmi -f $(REGISTRY)/openmatch-evaluator-simple:$(TAG) $(REGISTRY)/openmatch-evaluator-simple:$(ALTERNATE_TAG)
|
||||
|
||||
install-redis: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
$(HELM) upgrade --install --wait --debug redis stable/redis --namespace redis
|
||||
|
||||
chart-deps: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
(cd install/helm/open-match; $(HELM) dependency update)
|
||||
|
||||
print-chart: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
(cd install/helm; $(HELM) lint open-match; $(HELM) install --dry-run --debug open-match)
|
||||
|
||||
install-chart: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
$(HELM) upgrade --install --wait --debug open-match install/helm/open-match \
|
||||
--namespace=open-match \
|
||||
--set openmatch.image.registry=$(REGISTRY) \
|
||||
--set openmatch.image.tag=$(TAG)
|
||||
|
||||
install-example-chart: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
$(HELM) upgrade --install --wait --debug open-match-example install/helm/open-match-example \
|
||||
--namespace=open-match \
|
||||
--set openmatch.image.registry=$(REGISTRY) \
|
||||
--set openmatch.image.tag=$(TAG)
|
||||
|
||||
delete-example-chart: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
-$(HELM) delete --purge open-match-example
|
||||
|
||||
dry-chart: build/toolchain/bin/helm$(EXE_EXTENSION)
|
||||
$(HELM) upgrade --install --wait --debug --dry-run open-match install/helm/open-match \
|
||||
--namespace=open-match \
|
||||
--set openmatch.image.registry=$(REGISTRY) \
|
||||
--set openmatch.image.tag=$(TAG)
|
||||
|
||||
delete-chart: build/toolchain/bin/helm$(EXE_EXTENSION) build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
-$(HELM) delete --purge open-match
|
||||
-$(KUBECTL) delete crd prometheuses.monitoring.coreos.com
|
||||
-$(KUBECTL) delete crd servicemonitors.monitoring.coreos.com
|
||||
-$(KUBECTL) delete crd prometheusrules.monitoring.coreos.com
|
||||
|
||||
update-helm-deps:
|
||||
(cd install/helm/open-match; helm dependencies update)
|
||||
|
||||
install-toolchain: build/toolchain/bin/protoc$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION) build/toolchain/bin/kubectl$(EXE_EXTENSION) build/toolchain/bin/helm$(EXE_EXTENSION) build/toolchain/bin/minikube$(EXE_EXTENSION) build/toolchain/bin/skaffold$(EXE_EXTENSION) build/toolchain/bin/hugo$(EXE_EXTENSION) build/toolchain/python/
|
||||
|
||||
build/toolchain/bin/helm$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
mkdir -p $(TOOLCHAIN_DIR)/temp-helm
|
||||
cd $(TOOLCHAIN_DIR)/temp-helm && curl -Lo helm.tar.gz $(HELM_PACKAGE) && tar xvzf helm.tar.gz --strip-components 1
|
||||
mv $(TOOLCHAIN_DIR)/temp-helm/helm$(EXE_EXTENSION) $(TOOLCHAIN_BIN)/helm$(EXE_EXTENSION)
|
||||
mv $(TOOLCHAIN_DIR)/temp-helm/tiller$(EXE_EXTENSION) $(TOOLCHAIN_BIN)/tiller$(EXE_EXTENSION)
|
||||
rm -rf $(TOOLCHAIN_DIR)/temp-helm/
|
||||
|
||||
build/toolchain/bin/hugo$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
mkdir -p $(TOOLCHAIN_DIR)/temp-hugo
|
||||
cd $(TOOLCHAIN_DIR)/temp-hugo && curl -Lo hugo.tar.gz $(HUGO_PACKAGE) && tar xvzf hugo.tar.gz
|
||||
mv $(TOOLCHAIN_DIR)/temp-hugo/hugo$(EXE_EXTENSION) $(TOOLCHAIN_BIN)/hugo$(EXE_EXTENSION)
|
||||
rm -rf $(TOOLCHAIN_DIR)/temp-hugo/
|
||||
|
||||
build/toolchain/bin/minikube$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
curl -Lo minikube$(EXE_EXTENSION) $(MINIKUBE_PACKAGE)
|
||||
chmod +x minikube$(EXE_EXTENSION)
|
||||
mv minikube$(EXE_EXTENSION) $(TOOLCHAIN_BIN)/minikube$(EXE_EXTENSION)
|
||||
|
||||
build/toolchain/bin/kubectl$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
curl -Lo kubectl$(EXE_EXTENSION) $(KUBECTL_PACKAGE)
|
||||
chmod +x kubectl$(EXE_EXTENSION)
|
||||
mv kubectl$(EXE_EXTENSION) $(TOOLCHAIN_BIN)/kubectl$(EXE_EXTENSION)
|
||||
|
||||
build/toolchain/bin/skaffold$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
curl -Lo skaffold$(EXE_EXTENSION) $(SKAFFOLD_PACKAGE)
|
||||
chmod +x skaffold$(EXE_EXTENSION)
|
||||
mv skaffold$(EXE_EXTENSION) $(TOOLCHAIN_BIN)/skaffold$(EXE_EXTENSION)
|
||||
|
||||
push-helm: build/toolchain/bin/helm$(EXE_EXTENSION) build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
$(KUBECTL) create serviceaccount --namespace kube-system tiller
|
||||
$(HELM) init --service-account tiller --force-upgrade
|
||||
$(KUBECTL) create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
|
||||
ifneq ($(strip $($(KUBECTL) get clusterroles | grep -i rbac)),)
|
||||
$(KUBECTL) patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
|
||||
endif
|
||||
echo "Waiting for Tiller to become ready..."
|
||||
$(KUBECTL) wait deployment --timeout=60s --for condition=available -l app=helm,name=tiller --namespace kube-system
|
||||
|
||||
delete-helm: build/toolchain/bin/helm$(EXE_EXTENSION) build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
-$(HELM) reset
|
||||
-$(KUBECTL) delete serviceaccount --namespace kube-system tiller
|
||||
-$(KUBECTL) delete clusterrolebinding tiller-cluster-rule
|
||||
ifneq ($(strip $($(KUBECTL) get clusterroles | grep -i rbac)),)
|
||||
-$(KUBECTL) delete deployment --namespace kube-system tiller-deploy
|
||||
endif
|
||||
echo "Waiting for Tiller to go away..."
|
||||
-$(KUBECTL) wait deployment --timeout=60s --for delete -l app=helm,name=tiller --namespace kube-system
|
||||
|
||||
auth-docker:
|
||||
gcloud $(GCP_PROJECT_FLAG) auth configure-docker
|
||||
|
||||
auth-gke-cluster:
|
||||
gcloud $(GCP_PROJECT_FLAG) container clusters get-credentials $(GKE_CLUSTER_NAME) $(GCP_LOCATION_FLAG)
|
||||
|
||||
create-gke-cluster:
|
||||
gcloud $(GCP_PROJECT_FLAG) container clusters create $(GKE_CLUSTER_NAME) $(GCP_LOCATION_FLAG) --machine-type n1-standard-4 --tags open-match
|
||||
|
||||
delete-gke-cluster:
|
||||
gcloud $(GCP_PROJECT_FLAG) container clusters delete $(GKE_CLUSTER_NAME) $(GCP_LOCATION_FLAG)
|
||||
|
||||
create-mini-cluster: build/toolchain/bin/minikube$(EXE_EXTENSION)
|
||||
$(MINIKUBE) start --memory 6144 --cpus 4 --disk-size 50g
|
||||
|
||||
delete-mini-cluster: build/toolchain/bin/minikube$(EXE_EXTENSION)
|
||||
$(MINIKUBE) delete
|
||||
|
||||
build/toolchain/python/:
|
||||
mkdir -p build/toolchain/python/
|
||||
virtualenv --python=python3 build/toolchain/python/
|
||||
# Hack to workaround some crazy bug in pip that's chopping off python executable's name.
|
||||
cd build/toolchain/python/bin && ln -s python3 pytho
|
||||
cd build/toolchain/python/ && source bin/activate && pip install grpcio-tools && deactivate
|
||||
|
||||
build/toolchain/bin/protoc$(EXE_EXTENSION):
|
||||
mkdir -p $(TOOLCHAIN_BIN)
|
||||
curl -o $(TOOLCHAIN_DIR)/protoc-temp.zip -L $(PROTOC_PACKAGE)
|
||||
(cd $(TOOLCHAIN_DIR); unzip -o protoc-temp.zip)
|
||||
rm $(TOOLCHAIN_DIR)/protoc-temp.zip $(TOOLCHAIN_DIR)/readme.txt
|
||||
|
||||
build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION):
|
||||
$(GO) get github.com/golang/protobuf/protoc-gen-go
|
||||
$(GO) install github.com/golang/protobuf/protoc-gen-go
|
||||
mv $(GOPATH)/bin/protoc-gen-go$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION)
|
||||
|
||||
all-protos: internal/pb/backend.pb.go internal/pb/frontend.pb.go internal/pb/function.pb.go internal/pb/messages.pb.go internal/pb/mmlogic.pb.go mmlogic-simple-protos
|
||||
internal/pb/%.pb.go: api/protobuf-spec/%.proto build/toolchain/bin/protoc$(EXE_EXTENSION) build/toolchain/bin/protoc-gen-go$(EXE_EXTENSION)
|
||||
$(PROTOC) $< \
|
||||
-I $(CURDIR) -I $(PROTOC_INCLUDES) \
|
||||
--go_out=plugins=grpc:$(GOPATH)/src
|
||||
|
||||
## Include structure of the protos needs to be called out do the dependency chain is run through properly.
|
||||
internal/pb/backend.pb.go: internal/pb/messages.pb.go
|
||||
internal/pb/frontend.pb.go: internal/pb/messages.pb.go
|
||||
internal/pb/mmlogic.pb.go: internal/pb/messages.pb.go
|
||||
internal/pb/function.pb.go: internal/pb/messages.pb.go
|
||||
|
||||
mmlogic-simple-protos: examples/functions/python3/mmlogic-simple/api/protobuf_spec/messages_pb2.py examples/functions/python3/mmlogic-simple/api/protobuf_spec/mmlogic_pb2.py
|
||||
|
||||
examples/functions/python3/mmlogic-simple/api/protobuf_spec/%_pb2.py: api/protobuf-spec/%.proto build/toolchain/python/
|
||||
source build/toolchain/python/bin/activate && python3 -m grpc_tools.protoc -I $(CURDIR) -I $(PROTOC_INCLUDES) --python_out=examples/functions/python3/mmlogic-simple/ --grpc_python_out=examples/functions/python3/mmlogic-simple/ $< && deactivate
|
||||
|
||||
internal/pb/%_pb2.py: api/protobuf-spec/%.proto build/toolchain/python/
|
||||
source build/toolchain/python/bin/activate && python3 -m grpc_tools.protoc -I $(CURDIR) -I $(PROTOC_INCLUDES) --python_out=$(CURDIR) --grpc_python_out=$(CURDIR) $< && deactivate
|
||||
|
||||
build:
|
||||
$(GO) build ./...
|
||||
|
||||
test:
|
||||
$(GO) test ./... -race
|
||||
|
||||
fmt:
|
||||
$(GO) fmt ./...
|
||||
|
||||
vet:
|
||||
$(GO) vet ./...
|
||||
|
||||
cmd/backendapi/backendapi: internal/pb/backend.pb.go
|
||||
cd cmd/backendapi; $(GO_BUILD_COMMAND)
|
||||
|
||||
cmd/frontendapi/frontendapi: internal/pb/frontend.pb.go
|
||||
cd cmd/frontendapi; $(GO_BUILD_COMMAND)
|
||||
|
||||
cmd/mmforc/mmforc:
|
||||
cd cmd/mmforc; $(GO_BUILD_COMMAND)
|
||||
|
||||
cmd/mmlogicapi/mmlogicapi: internal/pb/mmlogic.pb.go
|
||||
cd cmd/mmlogicapi; $(GO_BUILD_COMMAND)
|
||||
|
||||
examples/backendclient/backendclient: internal/pb/backend.pb.go
|
||||
cd examples/backendclient; $(GO_BUILD_COMMAND)
|
||||
|
||||
examples/evaluators/golang/simple/simple: internal/pb/messages.pb.go
|
||||
cd examples/evaluators/golang/simple; $(GO_BUILD_COMMAND)
|
||||
|
||||
examples/functions/golang/manual-simple/manual-simple: internal/pb/messages.pb.go
|
||||
cd examples/functions/golang/manual-simple; $(GO_BUILD_COMMAND)
|
||||
|
||||
test/cmd/clientloadgen/clientloadgen:
|
||||
cd test/cmd/clientloadgen; $(GO_BUILD_COMMAND)
|
||||
|
||||
test/cmd/frontendclient/frontendclient: internal/pb/frontend.pb.go internal/pb/messages.pb.go
|
||||
cd test/cmd/frontendclient; $(GO_BUILD_COMMAND)
|
||||
|
||||
build/archives/${NODEJS_PACKAGE_NAME}:
|
||||
mkdir -p build/archives/
|
||||
cd build/archives/ && curl -L -o ${NODEJS_PACKAGE_NAME} ${NODEJS_PACKAGE}
|
||||
|
||||
build/toolchain/nodejs/: build/archives/${NODEJS_PACKAGE_NAME}
|
||||
mkdir -p build/toolchain/nodejs/
|
||||
cd build/toolchain/nodejs/ && tar xjf ../../archives/${NODEJS_PACKAGE_NAME} --strip-components 1
|
||||
|
||||
install-npm: build/toolchain/nodejs/
|
||||
echo "{}" > package.json
|
||||
$(TOOLCHAIN_DIR)/nodejs/bin/npm install postcss-cli autoprefixer
|
||||
|
||||
build/site/: build/archives/govanityurls.zip build/toolchain/bin/hugo$(EXE_EXTENSION)
|
||||
rm -rf build/site/
|
||||
mkdir -p build/site/
|
||||
cd site/ && ../build/toolchain/bin/hugo$(EXE_EXTENSION) --enableGitInfo --config=config.toml --source . --destination $(BUILD_DIR)/site/public/
|
||||
-cp -f site/* $(BUILD_DIR)/site
|
||||
#cd $(BUILD_DIR)/site && "SERVICE=$(SERVICE) envsubst < app.yaml > .app.yaml"
|
||||
cp $(BUILD_DIR)/site/app.yaml $(BUILD_DIR)/site/.app.yaml
|
||||
|
||||
browse-site: build/site/
|
||||
cd $(BUILD_DIR)/site && dev_appserver.py .app.yaml
|
||||
|
||||
deploy-dev-site: build/site/
|
||||
cd $(BUILD_DIR)/site && gcloud $(OM_SITE_GCP_PROJECT_FLAG) app deploy .app.yaml --promote --version=$(VERSION_SUFFIX) --quiet
|
||||
|
||||
run-site: build/toolchain/bin/hugo$(EXE_EXTENSION)
|
||||
cd site/ && ../build/toolchain/bin/hugo$(EXE_EXTENSION) server --debug --watch --enableGitInfo . --bind 0.0.0.0 --port $(SITE_PORT) --disableFastRender
|
||||
|
||||
all: service-binaries client-binaries example-binaries
|
||||
service-binaries: cmd/backendapi/backendapi cmd/frontendapi/frontendapi cmd/mmforc/mmforc cmd/mmlogicapi/mmlogicapi
|
||||
client-binaries: examples/backendclient/backendclient test/cmd/clientloadgen/clientloadgen test/cmd/frontendclient/frontendclient
|
||||
example-binaries: examples/evaluators/golang/simple/simple examples/functions/golang/manual-simple
|
||||
presubmit: fmt vet build test
|
||||
|
||||
clean-site:
|
||||
rm -rf build/site/
|
||||
|
||||
clean-protos:
|
||||
rm -rf internal/pb/
|
||||
rm -rf api/protobuf_spec/
|
||||
|
||||
clean-binaries:
|
||||
rm -rf cmd/backendapi/backendapi
|
||||
rm -rf cmd/frontendapi/frontendapi
|
||||
rm -rf cmd/mmforc/mmforc
|
||||
rm -rf cmd/mmlogicapi/mmlogicapi
|
||||
rm -rf examples/backendclient/backendclient
|
||||
rm -rf examples/evaluators/golang/simple/simple
|
||||
rm -rf examples/functions/golang/manual-simple/manual-simple
|
||||
rm -rf test/cmd/clientloadgen/clientloadgen
|
||||
rm -rf test/cmd/frontendclient/frontendclient
|
||||
|
||||
clean-toolchain:
|
||||
rm -rf build/toolchain/
|
||||
|
||||
clean-nodejs:
|
||||
rm -rf build/toolchain/nodejs/
|
||||
rm -rf node_modules/
|
||||
rm -rf package.json
|
||||
|
||||
clean: clean-images clean-binaries clean-site clean-toolchain clean-protos clean-nodejs
|
||||
|
||||
run-backendclient: build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
$(KUBECTL) run om-backendclient --rm --restart=Never --image-pull-policy=Always -i --tty --image=$(REGISTRY)/openmatch-backendclient:$(TAG) --namespace=open-match $(KUBECTL_RUN_ENV)
|
||||
|
||||
run-frontendclient: build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
$(KUBECTL) run om-frontendclient --rm --restart=Never --image-pull-policy=Always -i --tty --image=$(REGISTRY)/openmatch-frontendclient:$(TAG) --namespace=open-match $(KUBECTL_RUN_ENV)
|
||||
|
||||
run-clientloadgen: build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
$(KUBECTL) run om-clientloadgen --rm --restart=Never --image-pull-policy=Always -i --tty --image=$(REGISTRY)/openmatch-clientloadgen:$(TAG) --namespace=open-match $(KUBECTL_RUN_ENV)
|
||||
|
||||
proxy-grafana: build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
echo "User: admin"
|
||||
echo "Password: openmatch"
|
||||
$(KUBECTL) port-forward --namespace open-match $(shell $(KUBECTL) get pod --namespace open-match --selector="app=grafana,release=open-match" --output jsonpath='{.items[0].metadata.name}') $(GRAFANA_PORT):3000 $(PORT_FORWARD_ADDRESS_FLAG)
|
||||
|
||||
proxy-prometheus: build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
$(KUBECTL) port-forward --namespace open-match $(shell $(KUBECTL) get pod --namespace open-match --selector="app=prometheus,component=server,release=open-match" --output jsonpath='{.items[0].metadata.name}') $(PROMETHEUS_PORT):9090 $(PORT_FORWARD_ADDRESS_FLAG)
|
||||
|
||||
proxy-dashboard: build/toolchain/bin/kubectl$(EXE_EXTENSION)
|
||||
$(KUBECTL) port-forward --namespace kube-system $(shell $(KUBECTL) get pod --namespace kube-system --selector="app=kubernetes-dashboard" --output jsonpath='{.items[0].metadata.name}') $(DASHBOARD_PORT):9090 $(PORT_FORWARD_ADDRESS_FLAG)
|
||||
|
||||
.PHONY: proxy-dashboard proxy-prometheus proxy-grafana clean clean-toolchain clean-binaries clean-protos presubmit test vet
|
||||
|
64
README.md
64
README.md
@ -47,9 +47,9 @@ Open Match is designed to support massively concurrent matchmaking, and to be sc
|
||||
* **Ignore List** — Removing players from matchmaking consideration is accomplished using _ignore lists_. They contain lists of player IDs that your MMF should not include when making matches.
|
||||
|
||||
## Requirements
|
||||
* [Kubernetes](https://kubernetes.io/) cluster — tested with version 1.9.
|
||||
* [Kubernetes](https://kubernetes.io/) cluster — tested with version 1.11.7.
|
||||
* [Redis 4+](https://redis.io/) — tested with 4.0.11.
|
||||
* Open Match is compiled against the latest release of [Golang](https://golang.org/) — tested with 1.10.9.
|
||||
* Open Match is compiled against the latest release of [Golang](https://golang.org/) — tested with 1.11.5.
|
||||
|
||||
## Components
|
||||
|
||||
@ -179,7 +179,65 @@ Once we reach a 1.0 release, we plan to produce publicly available (Linux) Docke
|
||||
|
||||
### Compiling from source
|
||||
|
||||
All components of Open Match produce (Linux) Docker container images as artifacts, and there are included `Dockerfile`s for each. [Google Cloud Platform Cloud Build](https://cloud.google.com/cloud-build/docs/) users will also find `cloudbuild.yaml` files for each component in the corresponding `cmd/<COMPONENT>` directories.
|
||||
The easiest way to build Open Match is to use the Makefile. Before you can use the Makefile make sure you have the following dependencies:
|
||||
|
||||
```bash
|
||||
# Install Open Match Toolchain Dependencies (Debian other OSes including Mac OS X have similar dependencies)
|
||||
sudo apt-get update; sudo apt-get install -y python3 python3-virtualenv virtualenv make gcloud
|
||||
```
|
||||
|
||||
Go 1.11+ is also required. If your distro is new enough you can probably run `sudo apt-get install -y golang` or download the newest version from https://golang.org/.
|
||||
|
||||
To build all the artifacts of Open Match you can simply run the following commands.
|
||||
|
||||
```bash
|
||||
# Downloads all the tools needed to build Open Match
|
||||
make install-toolchain
|
||||
# Generates protocol buffer code files
|
||||
make all-protos
|
||||
# Builds all the binaries
|
||||
make all
|
||||
# Builds all the images.
|
||||
make build-images
|
||||
```
|
||||
|
||||
Once build you can use a command like `docker images` to see all the images that were build.
|
||||
|
||||
Before creating a pull request you can run `make local-cloud-build` to simulate a Cloud Build run to check for regressions.
|
||||
|
||||
The directory structure is a typical Go structure so if you do the following you should be able to work on this project within your IDE.
|
||||
|
||||
```bash
|
||||
cd $GOPATH
|
||||
mkdir -p src/github.com/GoogleCloudPlatform/
|
||||
cd src/github.com/GoogleCloudPlatform/
|
||||
# If you're going to contribute you'll want to fork open-match, see CONTRIBUTING.md for details.
|
||||
git clone https://github.com/GoogleCloudPlatform/open-match.git
|
||||
cd open-match
|
||||
# Open IDE in this directory.
|
||||
```
|
||||
|
||||
Lastly, this project uses go modules so you'll want to set `export GO111MODULE=on` before building.
|
||||
|
||||
## Zero to Open Match
|
||||
To deploy Open Match quickly to a Kubernetes cluster run these commands.
|
||||
|
||||
```bash
|
||||
# Downloads all the tools.
|
||||
make install-toolchain
|
||||
# Create a GKE Cluster
|
||||
make create-gke-cluster
|
||||
# OR Create a Minikube Cluster
|
||||
make create-mini-cluster
|
||||
# Install Helm
|
||||
make push-helm
|
||||
# Build and push images
|
||||
make push-images -j4
|
||||
# Deploy Open Match with example functions
|
||||
make install-chart install-example-chart
|
||||
```
|
||||
|
||||
## Docker Image Builds
|
||||
|
||||
All the core components for Open Match are written in Golang and use the [Dockerfile multistage builder pattern](https://docs.docker.com/develop/develop-images/multistage-build/). This pattern uses intermediate Docker containers as a Golang build environment while producing lightweight, minimized container images as final build artifacts. When the project is ready for production, we will modify the `Dockerfile`s to uncomment the last build stage. Although this pattern is great for production container images, it removes most of the utilities required to troubleshoot issues during development.
|
||||
|
||||
|
@ -4,12 +4,9 @@ This directory contains the API specification files for Open Match. API documena
|
||||
|
||||
* [Protobuf .proto files for all APIs](./protobuf-spec/)
|
||||
|
||||
These proto files are copied to the container image during `docker build` for the Open Match core components. The `Dockerfiles` handle the compilation for you transparently, and copy the resulting `SPEC.pb.go` files to the appropriate place in your final container image.
|
||||
|
||||
References:
|
||||
|
||||
* [gRPC](https://grpc.io/)
|
||||
* [Language Guide (proto3)](https://developers.google.com/protocol-buffers/docs/proto3)
|
||||
|
||||
Manual gRPC compilation commmand, from the directory containing the proto:
|
||||
```protoc -I . ./<filename>.proto --go_out=plugins=grpc:.```
|
||||
If you want to regenerate the golang gRPC modules (for local Open Match core component development, for example), the `protoc_go.sh` file in this directory may be of use to you!
|
||||
|
18
api/protobuf-spec/function.proto
Normal file
18
api/protobuf-spec/function.proto
Normal file
@ -0,0 +1,18 @@
|
||||
syntax = 'proto3';
|
||||
package api;
|
||||
option go_package = "github.com/GoogleCloudPlatform/open-match/internal/pb";
|
||||
|
||||
// The protobuf messages sent in the gRPC calls are defined 'messages.proto'.
|
||||
import 'api/protobuf-spec/messages.proto';
|
||||
|
||||
// The MMF proto defines the API for running MMFs as long-lived, 'serving'
|
||||
// functions inside of the kubernetes cluster.
|
||||
service Function {
|
||||
|
||||
// The assumption is that there will be one service for each MMF that is
|
||||
// being served. Build your MMF in the appropriate serving harness, deploy it
|
||||
// to the K8s cluster with a unique service name, then connect to that service
|
||||
// and call 'Run()' to execute the fuction.
|
||||
rpc Run(messages.Arguments) returns (messages.Result) {}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ message MatchObject{
|
||||
string error = 3; // Last error encountered.
|
||||
repeated Roster rosters = 4; // Rosters of players.
|
||||
repeated PlayerPool pools = 5; // 'Hard' filters, and the players who match them.
|
||||
string status = 6; // Resulting status of the match function
|
||||
}
|
||||
|
||||
// Data structure to hold a list of players in a match.
|
||||
@ -92,3 +93,23 @@ message Assignments{
|
||||
repeated Roster rosters = 1;
|
||||
string assignment = 10;
|
||||
}
|
||||
|
||||
// Messages for gRPC-served matchmaking functions.
|
||||
|
||||
// The message for passing in the per-request identifiers
|
||||
// to a matchmaking function; used so it knows which records to
|
||||
// write/update in state storage.
|
||||
message Request {
|
||||
string profile_id = 1;
|
||||
string proposal_id = 2;
|
||||
string request_id = 3;
|
||||
string error_id = 4;
|
||||
string timestamp = 5;
|
||||
}
|
||||
|
||||
// The message for passing all the necessary arguments to a
|
||||
// matchmaking function.
|
||||
message Arguments{
|
||||
Request request = 1;
|
||||
MatchObject matchobject = 2;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#!/bin/bash
|
||||
|
||||
python3 -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. mmlogic.proto
|
||||
python3 -m grpc_tools.protoc -I . --python_out=. --grpc_python_out=. messages.proto
|
||||
cp *pb2* $OM/examples/functions/python3/simple/.
|
||||
|
@ -19,6 +19,7 @@ cd $GOPATH/src
|
||||
protoc \
|
||||
${GOPATH}/src/github.com/GoogleCloudPlatform/open-match/api/protobuf-spec/backend.proto \
|
||||
${GOPATH}/src/github.com/GoogleCloudPlatform/open-match/api/protobuf-spec/frontend.proto \
|
||||
${GOPATH}/src/github.com/GoogleCloudPlatform/open-match/api/protobuf-spec/function.proto \
|
||||
${GOPATH}/src/github.com/GoogleCloudPlatform/open-match/api/protobuf-spec/mmlogic.proto \
|
||||
${GOPATH}/src/github.com/GoogleCloudPlatform/open-match/api/protobuf-spec/messages.proto \
|
||||
-I ${GOPATH}/src/github.com/GoogleCloudPlatform/open-match/ \
|
||||
|
295
cloudbuild.yaml
Normal file
295
cloudbuild.yaml
Normal file
@ -0,0 +1,295 @@
|
||||
# Copyright 2019 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
################################################################################
|
||||
# Open Match Script for Google Cloud Build #
|
||||
################################################################################
|
||||
|
||||
# To run this locally:
|
||||
# cloud-build-local --config=cloudbuild.yaml --dryrun=false --substitutions=_OM_VERSION=DEV .
|
||||
# To run this remotely:
|
||||
# gcloud builds submit --config=cloudbuild.yaml --substitutions=_OM_VERSION=DEV .
|
||||
|
||||
# Requires gcloud to be installed to work. (https://cloud.google.com/sdk/)
|
||||
# gcloud auth login
|
||||
# gcloud components install cloud-build-local
|
||||
|
||||
# This YAML contains all the build steps for building Open Match.
|
||||
# All PRs are verified against this script to prevent build breakages and regressions.
|
||||
|
||||
# Conventions
|
||||
# Each build step is ID'ed with "Prefix: Description".
|
||||
# The prefix portion determines what kind of step it is and it's impact.
|
||||
# Docker Image: Read-Only, outputs a docker image.
|
||||
# Lint: Read-Only, verifies correctness and formatting of a file.
|
||||
# Build: Read-Write, outputs a build artifact. Ok to run in parallel if the artifact will not collide with another one.
|
||||
# Generate: Read-Write, outputs files within /workspace that are used in other build step. Do not run these in parallel.
|
||||
# Setup: Read-Write, similar to generate but steps that run before any other step.
|
||||
|
||||
# Some useful things to know about Cloud Build.
|
||||
# The root of this repository is always stored in /workspace.
|
||||
# Any modifications that occur within /workspace are persisted between builds anything else is forgotten.
|
||||
# If a build step has intermediate files that need to be persisted for a future step then use volumes.
|
||||
# An example of this is the go-vol which is where the pkg/ data for go mod is stored.
|
||||
# More information here: https://cloud.google.com/cloud-build/docs/build-config#build_steps
|
||||
# A build step is basically a docker image that is tuned for Cloud Build,
|
||||
# https://github.com/GoogleCloudPlatform/cloud-builders/tree/master/go
|
||||
|
||||
steps:
|
||||
- id: 'Docker Image: open-match-base-build'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'open-match-base-build', '-f', 'Dockerfile.base-build', '.']
|
||||
waitFor: ['-']
|
||||
|
||||
- id: 'Docker Image: backendapi'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-backendapi:${_OM_VERSION}-${SHORT_SHA}', 'cmd/backendapi']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: frontendapi'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-frontendapi:${_OM_VERSION}-${SHORT_SHA}', 'cmd/frontendapi']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: mmforc'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-mmforc:${_OM_VERSION}-${SHORT_SHA}', 'cmd/mmforc']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: mmlogicapi'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-mmlogicapi:${_OM_VERSION}-${SHORT_SHA}', 'cmd/mmlogicapi']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: Evaluator Simple'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-evaluator-simple:${_OM_VERSION}-${SHORT_SHA}', 'examples/evaluators/golang/simple']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: openmatch-mmf-cs-mmlogic-simple'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-mmf-cs-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}', '.']
|
||||
dir: 'examples/functions/csharp/simple'
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: openmatch-mmf-go-mmlogic-simple'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-mmf-go-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}', '-f', 'examples/functions/golang/manual-simple/Dockerfile', '.']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: openmatch-mmf-php-mmlogic-simple'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-mmf-php-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}', '-f', 'examples/functions/php/mmlogic-simple/Dockerfile', '.']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: openmatch-mmf-py3-mmlogic-simple'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-mmf-py3-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}', '-f', 'examples/functions/python3/mmlogic-simple/Dockerfile', '.']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: backendclient'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-backendclient:${_OM_VERSION}-${SHORT_SHA}', 'examples/backendclient']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: clientloadgen'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-clientloadgen:${_OM_VERSION}-${SHORT_SHA}', 'test/cmd/clientloadgen']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
- id: 'Docker Image: frontendclient'
|
||||
name: gcr.io/cloud-builders/docker
|
||||
args: ['build', '-t', 'gcr.io/$PROJECT_ID/openmatch-frontendclient:${_OM_VERSION}-${SHORT_SHA}', 'test/cmd/frontendclient']
|
||||
waitFor: ['Docker Image: open-match-base-build']
|
||||
|
||||
# Cannot enable, produces lots of errors but can be useful.
|
||||
#- id: 'Lint: YAML Files'
|
||||
# name: wpengine/yamllint
|
||||
# args: ['/workspace']
|
||||
# waitFor: ['-']
|
||||
|
||||
- id: 'Lint: Kubernetes Configs'
|
||||
name: garethr/kubeval
|
||||
args: ['install/yaml/01-redis.yaml', 'install/yaml/02-open-match.yaml']
|
||||
waitFor: ['-']
|
||||
|
||||
- id: 'Setup: Pull Dependencies'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'CGO_ENABLED=0']
|
||||
args: ['go', 'mod', 'download']
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['-']
|
||||
|
||||
- id: 'Lint: Formatting'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'fmt', './...']
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Lint: Vetting'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'vet', './...']
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Test: 10x with Race Detection and Coverage'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off']
|
||||
args: ['go', 'test', './...', '-race', '-test.count', '10', '-cover']
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: All Binaries'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', './...']
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: cmd/backendapi/backendapi'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'cmd/backendapi/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: cmd/frontendapi/frontendapi'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'cmd/frontendapi/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: cmd/mmforc/mmforc'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'cmd/mmforc/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: cmd/mmlogicapi/mmlogicapi'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'cmd/mmlogicapi/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: examples/functions/golang/manual-simple'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'examples/functions/golang/manual-simple/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: examples/backendclient'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'examples/backendclient/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: test/cmd/clientloadgen'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'test/cmd/clientloadgen/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
- id: 'Build: test/cmd/frontendclient'
|
||||
name: golang
|
||||
env: ['GO111MODULE=on', 'GOPROXY=off', 'CGO_ENABLED=0']
|
||||
args: ['go', 'build', '-a', '-installsuffix', 'cgo', '.']
|
||||
dir: 'test/cmd/frontendclient/'
|
||||
volumes:
|
||||
- name: 'go-vol'
|
||||
path: '/go'
|
||||
waitFor: ['Setup: Pull Dependencies']
|
||||
|
||||
artifacts:
|
||||
objects:
|
||||
location: gs://open-match-build-artifacts/output/
|
||||
paths:
|
||||
- cmd/backendapi/backendapi
|
||||
- cmd/frontendapi/frontendapi
|
||||
- cmd/mmforc/mmforc
|
||||
- cmd/mmlogicapi/mmlogicapi
|
||||
- examples/functions/golang/manual-simple/manual-simple
|
||||
- examples/backendclient/backendclient
|
||||
- test/cmd/clientloadgen/clientloadgen
|
||||
- test/cmd/frontendclient/frontendclient
|
||||
images:
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-backendapi:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-frontendapi:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-mmforc:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-mmlogicapi:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-evaluator-simple:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-mmf-cs-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-mmf-go-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-mmf-php-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-mmf-py3-mmlogic-simple:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-backendclient:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-clientloadgen:${_OM_VERSION}-${SHORT_SHA}'
|
||||
- 'gcr.io/$PROJECT_ID/openmatch-frontendclient:${_OM_VERSION}-${SHORT_SHA}'
|
||||
substitutions:
|
||||
_OM_VERSION: 0.4.0
|
||||
logsBucket: 'gs://open-match-build-logs/'
|
||||
options:
|
||||
sourceProvenanceHash: ['SHA256']
|
||||
machineType: 'N1_HIGHCPU_8'
|
||||
# TODO: The build is slow because we don't vendor. go get takes a very long time.
|
||||
# Also we are rebuilding a lot of code unnecessarily. This should improve once
|
||||
# we have new hermetic and reproducible Dockerfiles.
|
||||
timeout: 1200s
|
||||
# TODO Build Steps
|
||||
# api/protobuf-spec/*: Build Protocol Buffers (golang, python, php)
|
||||
# config/matchmaker_config.yaml: Lint this file so it's verified as a valid YAML file.
|
||||
# deployments/k8s: Verify with kubelint.
|
||||
# examples/profiles/*.json: Verify valid JSON files.
|
||||
#
|
||||
# Consolidate many of these build steps via Makefile.
|
||||
# Caching of dependencies is a serious problem. Cloud Build does not complete within 20 minutes!
|
||||
|
@ -1,9 +0,0 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [
|
||||
'build',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-base:dev',
|
||||
'-f', 'Dockerfile.base',
|
||||
'.'
|
||||
]
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-base:dev']
|
@ -1,9 +0,0 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [
|
||||
'build',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-mmf-php-mmlogic-simple',
|
||||
'-f', 'Dockerfile.mmf_php',
|
||||
'.'
|
||||
]
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-mmf-php-mmlogic-simple']
|
@ -1,9 +0,0 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [
|
||||
'build',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-mmf-py3-mmlogic-simple:dev',
|
||||
'-f', 'Dockerfile.mmf_py3',
|
||||
'.'
|
||||
]
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-mmf-py3-mmlogic-simple:dev']
|
@ -1,10 +1,9 @@
|
||||
# Golang application builder steps
|
||||
FROM gcr.io/open-match-public-images/openmatch-base:dev as builder
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/cmd/backendapi
|
||||
COPY . .
|
||||
RUN go get -d -v
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/cmd/backendapi/
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo .
|
||||
|
||||
#FROM scratch
|
||||
#COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/backendapi/backendapi .
|
||||
ENTRYPOINT ["./backendapi"]
|
||||
FROM gcr.io/distroless/static
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/backendapi/backendapi .
|
||||
|
||||
ENTRYPOINT ["/backendapi"]
|
||||
|
@ -1,10 +1,8 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [ 'pull', 'gcr.io/$PROJECT_ID/openmatch-base:dev' ]
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [
|
||||
'build',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-backendapi:dev',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-backendapi:0.4',
|
||||
'.'
|
||||
]
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-backendapi:dev']
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-backendapi:0.4']
|
||||
|
@ -23,81 +23,9 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/GoogleCloudPlatform/open-match/cmd/backendapi/apisrv"
|
||||
"github.com/GoogleCloudPlatform/open-match/config"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/logging"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/metrics"
|
||||
redishelpers "github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/app/backendapi"
|
||||
)
|
||||
|
||||
var (
|
||||
// Logrus structured logging setup
|
||||
beLogFields = log.Fields{
|
||||
"app": "openmatch",
|
||||
"component": "backend",
|
||||
}
|
||||
beLog = log.WithFields(beLogFields)
|
||||
|
||||
// Viper config management setup
|
||||
cfg = viper.New()
|
||||
err = errors.New("")
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Add a hook to the logger to auto-count log lines for metrics output thru OpenCensus
|
||||
log.AddHook(metrics.NewHook(apisrv.BeLogLines, apisrv.KeySeverity))
|
||||
|
||||
// Viper config management initialization
|
||||
cfg, err = config.Read()
|
||||
if err != nil {
|
||||
beLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Unable to load config file")
|
||||
}
|
||||
|
||||
// Configure open match logging defaults
|
||||
logging.ConfigureLogging(cfg)
|
||||
|
||||
// Configure OpenCensus exporter to Prometheus
|
||||
// metrics.ConfigureOpenCensusPrometheusExporter expects that every OpenCensus view you
|
||||
// want to register is in an array, so append any views you want from other
|
||||
// packages to a single array here.
|
||||
ocServerViews := apisrv.DefaultBackendAPIViews // BackendAPI OpenCensus views.
|
||||
ocServerViews = append(ocServerViews, ocgrpc.DefaultServerViews...) // gRPC OpenCensus views.
|
||||
ocServerViews = append(ocServerViews, config.CfgVarCountView) // config loader view.
|
||||
// Waiting on https://github.com/opencensus-integrations/redigo/pull/1
|
||||
// ocServerViews = append(ocServerViews, redis.ObservabilityMetricViews...) // redis OpenCensus views.
|
||||
beLog.WithFields(log.Fields{"viewscount": len(ocServerViews)}).Info("Loaded OpenCensus views")
|
||||
metrics.ConfigureOpenCensusPrometheusExporter(cfg, ocServerViews)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
// Connect to redis
|
||||
pool := redishelpers.ConnectionPool(cfg)
|
||||
defer pool.Close()
|
||||
|
||||
// Instantiate the gRPC server with the connections we've made
|
||||
beLog.Info("Attempting to start gRPC server")
|
||||
srv := apisrv.New(cfg, pool)
|
||||
|
||||
// Run the gRPC server
|
||||
err := srv.Open()
|
||||
if err != nil {
|
||||
beLog.WithFields(log.Fields{"error": err.Error()}).Fatal("Failed to start gRPC server")
|
||||
}
|
||||
|
||||
// Exit when we see a signal
|
||||
terminate := make(chan os.Signal, 1)
|
||||
signal.Notify(terminate, os.Interrupt)
|
||||
<-terminate
|
||||
beLog.Info("Shutting down gRPC server")
|
||||
backendapi.RunApplication()
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
../../config/matchmaker_config.json
|
1
cmd/backendapi/matchmaker_config.yaml
Symbolic link
1
cmd/backendapi/matchmaker_config.yaml
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/matchmaker_config.yaml
|
@ -1,10 +1,9 @@
|
||||
# Golang application builder steps
|
||||
FROM gcr.io/open-match-public-images/openmatch-base:dev as builder
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/cmd/frontendapi
|
||||
COPY . .
|
||||
RUN go get -d -v
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/cmd/frontendapi/
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo .
|
||||
|
||||
#FROM scratch
|
||||
#COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/frontendapi/frontendapi .
|
||||
ENTRYPOINT ["./frontendapi"]
|
||||
FROM gcr.io/distroless/static
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/frontendapi/frontendapi .
|
||||
|
||||
ENTRYPOINT ["/frontendapi"]
|
||||
|
@ -1,10 +1,8 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [ 'pull', 'gcr.io/$PROJECT_ID/openmatch-base:dev' ]
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [
|
||||
'build',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-frontendapi:dev',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-frontendapi:0.4',
|
||||
'.'
|
||||
]
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-frontendapi:dev']
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-frontendapi:0.4']
|
||||
|
@ -19,87 +19,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/GoogleCloudPlatform/open-match/cmd/frontendapi/apisrv"
|
||||
"github.com/GoogleCloudPlatform/open-match/config"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/logging"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/metrics"
|
||||
redishelpers "github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/app/frontendapi"
|
||||
)
|
||||
|
||||
var (
|
||||
// Logrus structured logging setup
|
||||
feLogFields = log.Fields{
|
||||
"app": "openmatch",
|
||||
"component": "frontend",
|
||||
}
|
||||
feLog = log.WithFields(feLogFields)
|
||||
|
||||
// Viper config management setup
|
||||
cfg = viper.New()
|
||||
err = errors.New("")
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Add a hook to the logger to auto-count log lines for metrics output thru OpenCensus
|
||||
log.AddHook(metrics.NewHook(apisrv.FeLogLines, apisrv.KeySeverity))
|
||||
|
||||
// Add a hook to the logger to log the filename & line number.
|
||||
log.SetReportCaller(true)
|
||||
|
||||
// Viper config management initialization
|
||||
cfg, err = config.Read()
|
||||
if err != nil {
|
||||
feLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Unable to load config file")
|
||||
}
|
||||
|
||||
// Configure open match logging defaults
|
||||
logging.ConfigureLogging(cfg)
|
||||
|
||||
// Configure OpenCensus exporter to Prometheus
|
||||
// metrics.ConfigureOpenCensusPrometheusExporter expects that every OpenCensus view you
|
||||
// want to register is in an array, so append any views you want from other
|
||||
// packages to a single array here.
|
||||
ocServerViews := apisrv.DefaultFrontendAPIViews // FrontendAPI OpenCensus views.
|
||||
ocServerViews = append(ocServerViews, ocgrpc.DefaultServerViews...) // gRPC OpenCensus views.
|
||||
ocServerViews = append(ocServerViews, config.CfgVarCountView) // config loader view.
|
||||
// Waiting on https://github.com/opencensus-integrations/redigo/pull/1
|
||||
// ocServerViews = append(ocServerViews, redis.ObservabilityMetricViews...) // redis OpenCensus views.
|
||||
feLog.WithFields(log.Fields{"viewscount": len(ocServerViews)}).Info("Loaded OpenCensus views")
|
||||
metrics.ConfigureOpenCensusPrometheusExporter(cfg, ocServerViews)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
// Connect to redis
|
||||
pool := redishelpers.ConnectionPool(cfg)
|
||||
defer pool.Close()
|
||||
|
||||
// Instantiate the gRPC server with the connections we've made
|
||||
feLog.Info("Attempting to start gRPC server")
|
||||
srv := apisrv.New(cfg, pool)
|
||||
|
||||
// Run the gRPC server
|
||||
err := srv.Open()
|
||||
if err != nil {
|
||||
feLog.WithFields(log.Fields{"error": err.Error()}).Fatal("Failed to start gRPC server")
|
||||
}
|
||||
|
||||
// Exit when we see a signal
|
||||
terminate := make(chan os.Signal, 1)
|
||||
signal.Notify(terminate, os.Interrupt)
|
||||
<-terminate
|
||||
feLog.Info("Shutting down gRPC server")
|
||||
frontendapi.RunApplication()
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
../../config/matchmaker_config.json
|
1
cmd/frontendapi/matchmaker_config.yaml
Symbolic link
1
cmd/frontendapi/matchmaker_config.yaml
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/matchmaker_config.yaml
|
@ -1,21 +1,9 @@
|
||||
# Golang application builder steps
|
||||
FROM gcr.io/open-match-public-images/openmatch-base:dev as builder
|
||||
|
||||
# Necessary to get a specific version of the golang k8s client
|
||||
RUN go get github.com/tools/godep
|
||||
RUN go get k8s.io/client-go/...
|
||||
WORKDIR /go/src/k8s.io/client-go
|
||||
RUN git checkout v7.0.0
|
||||
RUN godep restore ./...
|
||||
RUN rm -rf vendor/
|
||||
RUN rm -rf /go/src/github.com/golang/protobuf/
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/cmd/mmforc/
|
||||
COPY . .
|
||||
RUN go get -d -v
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo .
|
||||
|
||||
# Uncomment to build production images (removes all troubleshooting tools)
|
||||
#FROM scratch
|
||||
#COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/mmforc/mmforc .
|
||||
CMD ["./mmforc"]
|
||||
FROM gcr.io/distroless/static
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/mmforc/mmforc .
|
||||
|
||||
ENTRYPOINT ["/mmforc"]
|
||||
|
@ -1,10 +1,8 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [ 'pull', 'gcr.io/$PROJECT_ID/openmatch-base:dev' ]
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [
|
||||
'build',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-mmforc:dev',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-mmforc:0.4',
|
||||
'.'
|
||||
]
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-mmforc:dev']
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-mmforc:0.4']
|
||||
|
@ -17,388 +17,13 @@ limitations under the License.
|
||||
// Note: the example only works with the code within the same release/branch.
|
||||
// This is based on the example from the official k8s golang client repository:
|
||||
// k8s.io/client-go/examples/create-update-delete-deployment/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/open-match/config"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/logging"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/metrics"
|
||||
redisHelpers "github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis"
|
||||
"github.com/tidwall/gjson"
|
||||
"go.opencensus.io/stats"
|
||||
"go.opencensus.io/tag"
|
||||
|
||||
"github.com/gomodule/redigo/redis"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
apiv1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
//"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
|
||||
// Uncomment the following line to load the gcp plugin (only required to authenticate against GKE clusters).
|
||||
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/app/mmforc"
|
||||
)
|
||||
|
||||
var (
|
||||
// Logrus structured logging setup
|
||||
mmforcLogFields = log.Fields{
|
||||
"app": "openmatch",
|
||||
"component": "mmforc",
|
||||
}
|
||||
mmforcLog = log.WithFields(mmforcLogFields)
|
||||
|
||||
// Viper config management setup
|
||||
cfg = viper.New()
|
||||
err = errors.New("")
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Add a hook to the logger to auto-count log lines for metrics output thru OpenCensus
|
||||
log.AddHook(metrics.NewHook(MmforcLogLines, KeySeverity))
|
||||
|
||||
// Viper config management initialization
|
||||
cfg, err = config.Read()
|
||||
if err != nil {
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Unable to load config file")
|
||||
}
|
||||
|
||||
// Configure open match logging defaults
|
||||
logging.ConfigureLogging(cfg)
|
||||
|
||||
// Configure OpenCensus exporter to Prometheus
|
||||
// metrics.ConfigureOpenCensusPrometheusExporter expects that every OpenCensus view you
|
||||
// want to register is in an array, so append any views you want from other
|
||||
// packages to a single array here.
|
||||
ocMmforcViews := DefaultMmforcViews // mmforc OpenCensus views.
|
||||
// Waiting on https://github.com/opencensus-integrations/redigo/pull/1
|
||||
// ocMmforcViews = append(ocMmforcViews, redis.ObservabilityMetricViews...) // redis OpenCensus views.
|
||||
mmforcLog.WithFields(log.Fields{"viewscount": len(ocMmforcViews)}).Info("Loaded OpenCensus views")
|
||||
metrics.ConfigureOpenCensusPrometheusExporter(cfg, ocMmforcViews)
|
||||
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
pool := redisHelpers.ConnectionPool(cfg)
|
||||
redisConn := pool.Get()
|
||||
defer redisConn.Close()
|
||||
|
||||
// Get k8s credentials so we can starts k8s Jobs
|
||||
mmforcLog.Info("Attempting to acquire k8s credentials")
|
||||
config, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mmforcLog.Info("K8s credentials acquired")
|
||||
|
||||
start := time.Now()
|
||||
checkProposals := true
|
||||
|
||||
// main loop; kick off matchmaker functions for profiles in the profile
|
||||
// queue and an evaluator when proposals are in the proposals queue
|
||||
for {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
_ = cancel
|
||||
|
||||
// Get profiles and kick off a job for each
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"profileQueueName": cfg.GetString("queues.profiles.name"),
|
||||
"pullCount": cfg.GetInt("queues.profiles.pullCount"),
|
||||
"query": "SPOP",
|
||||
"component": "statestorage",
|
||||
}).Debug("Retreiving match profiles")
|
||||
|
||||
results, err := redis.Strings(redisConn.Do("SPOP",
|
||||
cfg.GetString("queues.profiles.name"), cfg.GetInt("queues.profiles.pullCount")))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if len(results) > 0 {
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"numProfiles": len(results),
|
||||
}).Info("Starting MMF jobs...")
|
||||
|
||||
for _, profile := range results {
|
||||
// Kick off the job asynchrnously
|
||||
go mmfunc(ctx, profile, cfg, clientset, pool)
|
||||
// Count the number of jobs running
|
||||
redisHelpers.Increment(context.Background(), pool, "concurrentMMFs")
|
||||
}
|
||||
} else {
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"profileQueueName": cfg.GetString("queues.profiles.name"),
|
||||
}).Info("Unable to retreive match profiles from statestorage - have you entered any?")
|
||||
}
|
||||
|
||||
// Check to see if we should run the evaluator.
|
||||
// Get number of running MMFs
|
||||
r, err := redisHelpers.Retrieve(context.Background(), pool, "concurrentMMFs")
|
||||
|
||||
if err != nil {
|
||||
if err.Error() == "redigo: nil returned" {
|
||||
// No MMFs have run since we last evaluated; reset timer and loop
|
||||
mmforcLog.Debug("Number of concurrentMMFs is nil")
|
||||
start = time.Now()
|
||||
time.Sleep(1000 * time.Millisecond)
|
||||
}
|
||||
continue
|
||||
}
|
||||
numRunning, err := strconv.Atoi(r)
|
||||
if err != nil {
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Issue retrieving number of currently running MMFs")
|
||||
}
|
||||
|
||||
// We are ready to evaluate either when all MMFs are complete, or the
|
||||
// timeout is reached.
|
||||
//
|
||||
// Tuning how frequently the evaluator runs is a complex topic and
|
||||
// probably only of interest to users running large-scale production
|
||||
// workloads with many concurrently running matchmaking functions,
|
||||
// which have some overlap in the matchmaking player pools. Suffice to
|
||||
// say that under load, this switch should almost always trigger the
|
||||
// timeout interval code path. The concurrentMMFs check to see how
|
||||
// many are still running is meant as a deadman's switch to prevent
|
||||
// waiting to run the evaluator when all your MMFs are already
|
||||
// finished.
|
||||
switch {
|
||||
case time.Since(start).Seconds() >= float64(cfg.GetInt("evaluator.interval")):
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"interval": cfg.GetInt("evaluator.interval"),
|
||||
}).Info("Maximum evaluator interval exceeded")
|
||||
checkProposals = true
|
||||
|
||||
// Opencensus tagging
|
||||
ctx, _ = tag.New(ctx, tag.Insert(KeyEvalReason, "interval_exceeded"))
|
||||
case numRunning <= 0:
|
||||
mmforcLog.Info("All MMFs complete")
|
||||
checkProposals = true
|
||||
numRunning = 0
|
||||
ctx, _ = tag.New(ctx, tag.Insert(KeyEvalReason, "mmfs_completed"))
|
||||
}
|
||||
|
||||
if checkProposals {
|
||||
// Make sure there are proposals in the queue. No need to run the
|
||||
// evaluator if there are none.
|
||||
checkProposals = false
|
||||
mmforcLog.Info("Checking statestorage for match object proposals")
|
||||
results, err := redisHelpers.Count(context.Background(), pool, cfg.GetString("queues.proposals.name"))
|
||||
switch {
|
||||
case err != nil:
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Couldn't retrieve the length of the proposal queue from statestorage!")
|
||||
case results == 0:
|
||||
mmforcLog.WithFields(log.Fields{}).Warn("No proposals in the queue!")
|
||||
default:
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"numProposals": results,
|
||||
}).Info("Proposals available, evaluating!")
|
||||
go evaluator(ctx, cfg, clientset)
|
||||
}
|
||||
err = redisHelpers.Delete(context.Background(), pool, "concurrentMMFs")
|
||||
if err != nil {
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Error deleting concurrent MMF counter!")
|
||||
}
|
||||
start = time.Now()
|
||||
}
|
||||
|
||||
// TODO: Make this tunable via config.
|
||||
// A sleep here is not critical but just a useful safety valve in case
|
||||
// things are broken, to keep the main loop from going all-out and spamming the log.
|
||||
mainSleep := 1000
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"ms": mainSleep,
|
||||
}).Info("Sleeping...")
|
||||
time.Sleep(time.Duration(mainSleep) * time.Millisecond)
|
||||
} // End main for loop
|
||||
mmforc.RunApplication()
|
||||
}
|
||||
|
||||
// mmfunc generates a k8s job that runs the specified mmf container image.
|
||||
// resultsID is the redis key that the Backend API is monitoring for results; we can 'short circuit' and write errors directly to this key if we can't run the MMF for some reason.
|
||||
func mmfunc(ctx context.Context, resultsID string, cfg *viper.Viper, clientset *kubernetes.Clientset, pool *redis.Pool) {
|
||||
|
||||
// Generate the various keys/names, some of which must be populated to the k8s job.
|
||||
imageName := cfg.GetString("defaultImages.mmf.name") + ":" + cfg.GetString("defaultImages.mmf.tag")
|
||||
jobType := "mmf"
|
||||
ids := strings.Split(resultsID, ".") // comes in as dot-concatinated moID and profID.
|
||||
moID := ids[0]
|
||||
profID := ids[1]
|
||||
timestamp := strconv.Itoa(int(time.Now().Unix()))
|
||||
jobName := timestamp + "." + moID + "." + profID + "." + jobType
|
||||
propID := "proposal." + timestamp + "." + moID + "." + profID
|
||||
|
||||
// Extra fields for structured logging
|
||||
lf := log.Fields{"jobName": jobName}
|
||||
if cfg.GetBool("debug") { // Log a lot more info.
|
||||
lf = log.Fields{
|
||||
"jobType": jobType,
|
||||
"backendMatchObject": moID,
|
||||
"profile": profID,
|
||||
"jobTimestamp": timestamp,
|
||||
"containerImage": imageName,
|
||||
"jobName": jobName,
|
||||
"profileImageJSONKey": cfg.GetString("jsonkeys.mmfImage"),
|
||||
}
|
||||
}
|
||||
mmfuncLog := mmforcLog.WithFields(lf)
|
||||
|
||||
// Read the full profile from redis and access any keys that are important to deciding how MMFs are run.
|
||||
// TODO: convert this to using redispb and directly access the protobuf message instead of retrieving as a map?
|
||||
profile, err := redisHelpers.RetrieveAll(ctx, pool, profID)
|
||||
if err != nil {
|
||||
// Log failure to read this profile and return - won't run an MMF for an unreadable profile.
|
||||
mmfuncLog.WithFields(log.Fields{"error": err.Error()}).Error("Failure retreiving profile from statestorage")
|
||||
return
|
||||
}
|
||||
|
||||
// Got profile from state storage, make sure it is valid
|
||||
if gjson.Valid(profile["properties"]) {
|
||||
profileImage := gjson.Get(profile["properties"], cfg.GetString("jsonkeys.mmfImage"))
|
||||
if profileImage.Exists() {
|
||||
imageName = profileImage.String()
|
||||
mmfuncLog = mmfuncLog.WithFields(log.Fields{"containerImage": imageName})
|
||||
} else {
|
||||
mmfuncLog.Warn("Failed to read image name from profile at configured json key, using default image instead")
|
||||
}
|
||||
}
|
||||
mmfuncLog.Info("Attempting to create mmf k8s job")
|
||||
|
||||
// Kick off k8s job
|
||||
envvars := []apiv1.EnvVar{
|
||||
{Name: "MMF_PROFILE_ID", Value: profID},
|
||||
{Name: "MMF_PROPOSAL_ID", Value: propID},
|
||||
{Name: "MMF_REQUEST_ID", Value: moID},
|
||||
{Name: "MMF_ERROR_ID", Value: resultsID},
|
||||
{Name: "MMF_TIMESTAMP", Value: timestamp},
|
||||
}
|
||||
err = submitJob(clientset, jobType, jobName, imageName, envvars)
|
||||
if err != nil {
|
||||
// Record failure & log
|
||||
stats.Record(ctx, mmforcMmfFailures.M(1))
|
||||
mmfuncLog.WithFields(log.Fields{"error": err.Error()}).Error("MMF job submission failure!")
|
||||
} else {
|
||||
// Record Success
|
||||
stats.Record(ctx, mmforcMmfs.M(1))
|
||||
}
|
||||
}
|
||||
|
||||
// evaluator generates a k8s job that runs the specified evaluator container image.
|
||||
func evaluator(ctx context.Context, cfg *viper.Viper, clientset *kubernetes.Clientset) {
|
||||
|
||||
imageName := cfg.GetString("defaultImages.evaluator.name") + ":" + cfg.GetString("defaultImages.evaluator.tag")
|
||||
// Generate the job name
|
||||
timestamp := strconv.Itoa(int(time.Now().Unix()))
|
||||
jobType := "evaluator"
|
||||
jobName := timestamp + "." + jobType
|
||||
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"jobName": jobName,
|
||||
"containerImage": imageName,
|
||||
}).Info("Attempting to create evaluator k8s job")
|
||||
|
||||
// Kick off k8s job
|
||||
envvars := []apiv1.EnvVar{{Name: "MMF_TIMESTAMP", Value: timestamp}}
|
||||
err = submitJob(clientset, jobType, jobName, imageName, envvars)
|
||||
if err != nil {
|
||||
// Record failure & log
|
||||
stats.Record(ctx, mmforcEvalFailures.M(1))
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
"jobName": jobName,
|
||||
"containerImage": imageName,
|
||||
}).Error("Evaluator job submission failure!")
|
||||
} else {
|
||||
// Record success
|
||||
stats.Record(ctx, mmforcEvals.M(1))
|
||||
}
|
||||
}
|
||||
|
||||
// submitJob submits a job to kubernetes
|
||||
func submitJob(clientset *kubernetes.Clientset, jobType string, jobName string, imageName string, envvars []apiv1.EnvVar) error {
|
||||
|
||||
// DEPRECATED: will be removed in a future vrsion. Please switch to using the 'MMF_*' environment variables.
|
||||
v := strings.Split(jobName, ".")
|
||||
envvars = append(envvars, apiv1.EnvVar{Name: "PROFILE", Value: strings.Join(v[:len(v)-1], ".")})
|
||||
|
||||
job := &batchv1.Job{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: jobName,
|
||||
},
|
||||
Spec: batchv1.JobSpec{
|
||||
Completions: int32Ptr(1),
|
||||
Template: apiv1.PodTemplateSpec{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Labels: map[string]string{
|
||||
"app": jobType,
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
// Unused; here as an example.
|
||||
// Later we can put things more complicated than
|
||||
// env vars here and read them using k8s downward API
|
||||
// volumes
|
||||
"profile": jobName,
|
||||
},
|
||||
},
|
||||
Spec: apiv1.PodSpec{
|
||||
RestartPolicy: "Never",
|
||||
Containers: []apiv1.Container{
|
||||
{
|
||||
Name: jobType,
|
||||
Image: imageName,
|
||||
ImagePullPolicy: "Always",
|
||||
Env: envvars,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Get the namespace for the job from the current namespace, otherwise, use default
|
||||
namespace := os.Getenv("METADATA_NAMESPACE")
|
||||
if len(namespace) == 0 {
|
||||
namespace = apiv1.NamespaceDefault
|
||||
}
|
||||
|
||||
// Submit kubernetes job
|
||||
jobsClient := clientset.BatchV1().Jobs(namespace)
|
||||
result, err := jobsClient.Create(job)
|
||||
if err != nil {
|
||||
// TODO: replace queued profiles if things go south
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Couldn't create k8s job!")
|
||||
}
|
||||
|
||||
mmforcLog.WithFields(log.Fields{
|
||||
"jobName": result.GetObjectMeta().GetName(),
|
||||
}).Info("Created job.")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// readability functions used by generateJobSpec
|
||||
func int32Ptr(i int32) *int32 { return &i }
|
||||
func strPtr(i string) *string { return &i }
|
||||
|
@ -1 +0,0 @@
|
||||
../../config/matchmaker_config.json
|
1
cmd/mmforc/matchmaker_config.yaml
Symbolic link
1
cmd/mmforc/matchmaker_config.yaml
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/matchmaker_config.yaml
|
@ -1,10 +1,9 @@
|
||||
# Golang application builder steps
|
||||
FROM gcr.io/open-match-public-images/openmatch-base:dev as builder
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/cmd/mmlogicapi
|
||||
COPY . .
|
||||
RUN go get -d -v
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/cmd/mmlogicapi/
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo .
|
||||
|
||||
#FROM scratch
|
||||
#COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/frontendapi/frontendapi .
|
||||
ENTRYPOINT ["./mmlogicapi"]
|
||||
FROM gcr.io/distroless/static
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/cmd/mmlogicapi/mmlogicapi .
|
||||
|
||||
ENTRYPOINT ["/mmlogicapi"]
|
||||
|
@ -1,10 +1,8 @@
|
||||
steps:
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [ 'pull', 'gcr.io/$PROJECT_ID/openmatch-base:dev' ]
|
||||
- name: 'gcr.io/cloud-builders/docker'
|
||||
args: [
|
||||
'build',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-mmlogicapi:dev',
|
||||
'--tag=gcr.io/$PROJECT_ID/openmatch-mmlogicapi:0.4',
|
||||
'.'
|
||||
]
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-mmlogicapi:dev']
|
||||
images: ['gcr.io/$PROJECT_ID/openmatch-mmlogicapi:0.4']
|
||||
|
@ -22,83 +22,9 @@ limitations under the License.
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/signal"
|
||||
|
||||
"github.com/GoogleCloudPlatform/open-match/cmd/mmlogicapi/apisrv"
|
||||
"github.com/GoogleCloudPlatform/open-match/config"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/metrics"
|
||||
redisHelpers "github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"go.opencensus.io/plugin/ocgrpc"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/app/mmlogicapi"
|
||||
)
|
||||
|
||||
var (
|
||||
// Logrus structured logging setup
|
||||
mlLogFields = log.Fields{
|
||||
"app": "openmatch",
|
||||
"component": "mmlogic",
|
||||
}
|
||||
mlLog = log.WithFields(mlLogFields)
|
||||
|
||||
// Viper config management setup
|
||||
cfg = viper.New()
|
||||
err = errors.New("")
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Logrus structured logging initialization
|
||||
// Add a hook to the logger to auto-count log lines for metrics output thru OpenCensus
|
||||
log.AddHook(metrics.NewHook(apisrv.MlLogLines, apisrv.KeySeverity))
|
||||
|
||||
// Viper config management initialization
|
||||
cfg, err = config.Read()
|
||||
if err != nil {
|
||||
mlLog.WithFields(log.Fields{
|
||||
"error": err.Error(),
|
||||
}).Error("Unable to load config file")
|
||||
}
|
||||
|
||||
if cfg.GetBool("debug") == true {
|
||||
log.SetLevel(log.DebugLevel) // debug only, verbose - turn off in production!
|
||||
mlLog.Warn("Debug logging configured. Not recommended for production!")
|
||||
}
|
||||
|
||||
// Configure OpenCensus exporter to Prometheus
|
||||
// metrics.ConfigureOpenCensusPrometheusExporter expects that every OpenCensus view you
|
||||
// want to register is in an array, so append any views you want from other
|
||||
// packages to a single array here.
|
||||
ocServerViews := apisrv.DefaultMmlogicAPIViews // Matchmaking logic API OpenCensus views.
|
||||
ocServerViews = append(ocServerViews, ocgrpc.DefaultServerViews...) // gRPC OpenCensus views.
|
||||
ocServerViews = append(ocServerViews, config.CfgVarCountView) // config loader view.
|
||||
// Waiting on https://github.com/opencensus-integrations/redigo/pull/1
|
||||
// ocServerViews = append(ocServerViews, redis.ObservabilityMetricViews...) // redis OpenCensus views.
|
||||
mlLog.WithFields(log.Fields{"viewscount": len(ocServerViews)}).Info("Loaded OpenCensus views")
|
||||
metrics.ConfigureOpenCensusPrometheusExporter(cfg, ocServerViews)
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
// Connect to redis
|
||||
pool := redisHelpers.ConnectionPool(cfg)
|
||||
defer pool.Close()
|
||||
|
||||
// Instantiate the gRPC server with the connections we've made
|
||||
mlLog.Info("Attempting to start gRPC server")
|
||||
srv := apisrv.New(cfg, pool)
|
||||
|
||||
// Run the gRPC server
|
||||
err := srv.Open()
|
||||
if err != nil {
|
||||
mlLog.WithFields(log.Fields{"error": err.Error()}).Fatal("Failed to start gRPC server")
|
||||
}
|
||||
|
||||
// Exit when we see a signal
|
||||
terminate := make(chan os.Signal, 1)
|
||||
signal.Notify(terminate, os.Interrupt)
|
||||
<-terminate
|
||||
mlLog.Info("Shutting down gRPC server")
|
||||
mmlogicapi.RunApplication()
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
../../config/matchmaker_config.json
|
1
cmd/mmlogicapi/matchmaker_config.yaml
Symbolic link
1
cmd/mmlogicapi/matchmaker_config.yaml
Symbolic link
@ -0,0 +1 @@
|
||||
../../config/matchmaker_config.yaml
|
@ -41,12 +41,20 @@ var (
|
||||
// REDIS_SENTINEL_PORT_6379_TCP_PORT=6379
|
||||
// REDIS_SENTINEL_PORT_6379_TCP_PROTO=tcp
|
||||
// REDIS_SENTINEL_SERVICE_HOST=10.55.253.195
|
||||
//
|
||||
// MMFs are expected to get their configuation from env vars instead
|
||||
// of reading the config file. So, config parameters that are required
|
||||
// by MMFs should be populated to env vars.
|
||||
envMappings = map[string]string{
|
||||
"redis.user": "REDIS_USER",
|
||||
"redis.password": "REDIS_PASSWORD",
|
||||
"redis.hostname": "REDIS_SERVICE_HOST",
|
||||
"redis.port": "REDIS_SERVICE_PORT",
|
||||
"redis.pool.maxIdle": "REDIS_POOL_MAXIDLE",
|
||||
"redis.pool.maxActive": "REDIS_POOL_MAXACTIVE",
|
||||
"redis.pool.idleTimeout": "REDIS_POOL_IDLETIMEOUT",
|
||||
"api.mmlogic.hostname": "OM_MMLOGICAPI_SERVICE_HOST",
|
||||
"api.mmlogic.port": "OM_MMLOGICAPI_SERVICE_PORT",
|
||||
}
|
||||
|
||||
// Viper config management setup
|
||||
@ -74,6 +82,7 @@ func Read() (*viper.Viper, error) {
|
||||
cfg.SetConfigType("yaml")
|
||||
cfg.SetConfigName("matchmaker_config")
|
||||
cfg.AddConfigPath(".")
|
||||
cfg.AddConfigPath("config")
|
||||
|
||||
// Read in config file using Viper
|
||||
err := cfg.ReadInConfig()
|
||||
|
@ -1,110 +0,0 @@
|
||||
{
|
||||
"debug": true,
|
||||
"logging":{
|
||||
"level": "debug",
|
||||
"format": "text",
|
||||
"source": true
|
||||
},
|
||||
"api": {
|
||||
"backend": {
|
||||
"hostname": "om-backendapi",
|
||||
"port": 50505,
|
||||
"timeout": 90
|
||||
},
|
||||
"frontend": {
|
||||
"hostname": "om-frontendapi",
|
||||
"port": 50504,
|
||||
"timeout": 300
|
||||
},
|
||||
"mmlogic": {
|
||||
"hostname": "om-mmlogicapi",
|
||||
"port": 50503
|
||||
}
|
||||
},
|
||||
"evalutor": {
|
||||
"interval": 10
|
||||
},
|
||||
"metrics": {
|
||||
"port": 9555,
|
||||
"endpoint": "/metrics",
|
||||
"reportingPeriod": 5
|
||||
},
|
||||
"queues": {
|
||||
"profiles": {
|
||||
"name": "profileq",
|
||||
"pullCount": 100
|
||||
},
|
||||
"proposals": {
|
||||
"name": "proposalq"
|
||||
}
|
||||
},
|
||||
"ignoreLists": {
|
||||
"proposed": {
|
||||
"name": "proposed",
|
||||
"offset": 0,
|
||||
"duration": 800
|
||||
},
|
||||
"deindexed": {
|
||||
"name": "deindexed",
|
||||
"offset": 0,
|
||||
"duration": 800
|
||||
},
|
||||
"expired": {
|
||||
"name": "OM_METADATA.accessed",
|
||||
"offset": 800,
|
||||
"duration": 0
|
||||
}
|
||||
},
|
||||
"defaultImages": {
|
||||
"evaluator": {
|
||||
"name": "gcr.io/open-match-public-images/openmatch-evaluator",
|
||||
"tag": "dev"
|
||||
},
|
||||
"mmf": {
|
||||
"name": "gcr.io/open-match-public-images/openmatch-mmf-py3-mmlogic-simple",
|
||||
"tag": "dev"
|
||||
}
|
||||
},
|
||||
"redis": {
|
||||
"user": "",
|
||||
"password": "",
|
||||
"pool" : {
|
||||
"maxIdle" : 3,
|
||||
"maxActive" : 0,
|
||||
"idleTimeout" : 60
|
||||
},
|
||||
"queryArgs":{
|
||||
"count": 10000
|
||||
},
|
||||
"results": {
|
||||
"pageSize": 10000
|
||||
},
|
||||
"expirations": {
|
||||
"player": 43200,
|
||||
"matchobject":43200
|
||||
}
|
||||
},
|
||||
"jsonkeys": {
|
||||
"mmfImage": "imagename",
|
||||
"rosters": "properties.rosters",
|
||||
"pools": "properties.pools"
|
||||
},
|
||||
"playerIndices": [
|
||||
"char.cleric",
|
||||
"char.knight",
|
||||
"char.paladin",
|
||||
"map.aleroth",
|
||||
"map.oasis",
|
||||
"mmr.rating",
|
||||
"mode.battleroyale",
|
||||
"mode.ctf",
|
||||
"region.europe-east1",
|
||||
"region.europe-west1",
|
||||
"region.europe-west2",
|
||||
"region.europe-west3",
|
||||
"region.europe-west4",
|
||||
"role.dps",
|
||||
"role.support",
|
||||
"role.tank"
|
||||
]
|
||||
}
|
97
config/matchmaker_config.yaml
Normal file
97
config/matchmaker_config.yaml
Normal file
@ -0,0 +1,97 @@
|
||||
# kubectl create configmap om-configmap --from-file=config/matchmaker_config.yaml
|
||||
debug: true
|
||||
|
||||
logging:
|
||||
level: debug
|
||||
format: text
|
||||
source: true
|
||||
|
||||
api:
|
||||
backend:
|
||||
hostname: om-backendapi
|
||||
port: 50505
|
||||
backoff: "[2 32] *2 ~0.33 <30"
|
||||
frontend:
|
||||
hostname: om-frontendapi
|
||||
port: 50504
|
||||
backoff: "[2 32] *2 ~0.33 <300"
|
||||
mmlogic:
|
||||
hostname: om-mmlogicapi
|
||||
port: 50503
|
||||
functions:
|
||||
port: 50502
|
||||
|
||||
evalutor:
|
||||
interval: 10
|
||||
|
||||
metrics:
|
||||
port: 9555
|
||||
endpoint: /metrics
|
||||
reportingPeriod: 5
|
||||
|
||||
queues:
|
||||
profiles:
|
||||
name: profileq
|
||||
pullCount: 100
|
||||
proposals:
|
||||
name: proposalq
|
||||
|
||||
ignoreLists:
|
||||
proposed:
|
||||
name: proposed
|
||||
offset: 0
|
||||
duration: 800
|
||||
deindexed:
|
||||
name: deindexed
|
||||
offset: 0
|
||||
duration: 800
|
||||
expired:
|
||||
name: OM_METADATA.accessed
|
||||
offset: 800
|
||||
duration: 0
|
||||
|
||||
defaultImages:
|
||||
evaluator:
|
||||
name: gcr.io/matchmaker-dev-201405/openmatch-evaluator
|
||||
tag: dev
|
||||
mmf:
|
||||
name: gcr.io/matchmaker-dev-201405/openmatch-mmf-py3-mmlogic-simple
|
||||
tag: dev
|
||||
|
||||
redis:
|
||||
pool:
|
||||
maxIdle: 3
|
||||
maxActive: 0
|
||||
idleTimeout: 60
|
||||
queryArgs:
|
||||
count: 10000
|
||||
results:
|
||||
pageSize: 10000
|
||||
expirations:
|
||||
player: 43200
|
||||
matchobject: 43200
|
||||
|
||||
jsonkeys:
|
||||
mmfImage: imagename
|
||||
mmfService: hostname
|
||||
rosters: properties.rosters
|
||||
pools: properties.pools
|
||||
|
||||
playerIndices:
|
||||
- char.cleric
|
||||
- char.knight
|
||||
- char.paladin
|
||||
- map.aleroth
|
||||
- map.oasis
|
||||
- mmr.rating
|
||||
- mode.battleroyale
|
||||
- mode.ctf
|
||||
- mode.demo
|
||||
- region.europe-east1
|
||||
- region.europe-west1
|
||||
- region.europe-west2
|
||||
- region.europe-west3
|
||||
- region.europe-west4
|
||||
- role.dps
|
||||
- role.support
|
||||
- role.tank
|
@ -1,53 +0,0 @@
|
||||
{
|
||||
"apiVersion":"extensions/v1beta1",
|
||||
"kind":"Deployment",
|
||||
"metadata":{
|
||||
"name":"om-backendapi",
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "backend"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"replicas":1,
|
||||
"selector":{
|
||||
"matchLabels":{
|
||||
"app":"openmatch",
|
||||
"component": "backend"
|
||||
}
|
||||
},
|
||||
"template":{
|
||||
"metadata":{
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "backend"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"containers":[
|
||||
{
|
||||
"name":"om-backend",
|
||||
"image":"gcr.io/open-match-public-images/openmatch-backendapi:dev",
|
||||
"imagePullPolicy":"Always",
|
||||
"ports": [
|
||||
{
|
||||
"name": "grpc",
|
||||
"containerPort": 50505
|
||||
},
|
||||
{
|
||||
"name": "metrics",
|
||||
"containerPort": 9555
|
||||
}
|
||||
],
|
||||
"resources":{
|
||||
"requests":{
|
||||
"memory":"100Mi",
|
||||
"cpu":"100m"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
deployments/k8s/backendapi_deployment.yaml
Normal file
32
deployments/k8s/backendapi_deployment.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: om-backendapi
|
||||
labels:
|
||||
app: openmatch
|
||||
component: backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: openmatch
|
||||
component: backend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: openmatch
|
||||
component: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: om-backend
|
||||
image: gcr.io/open-match-public-images/openmatch-backendapi:dev
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: grpc
|
||||
containerPort: 50505
|
||||
- name: metrics
|
||||
containerPort: 9555
|
||||
resources:
|
||||
requests:
|
||||
memory: 100Mi
|
||||
cpu: 100m
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "om-backendapi"
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app": "openmatch",
|
||||
"component": "backend"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 50505,
|
||||
"targetPort": "grpc"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
12
deployments/k8s/backendapi_service.yaml
Normal file
12
deployments/k8s/backendapi_service.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: om-backendapi
|
||||
spec:
|
||||
selector:
|
||||
app: openmatch
|
||||
component: backend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 50505
|
||||
targetPort: grpc
|
@ -1,53 +0,0 @@
|
||||
{
|
||||
"apiVersion":"extensions/v1beta1",
|
||||
"kind":"Deployment",
|
||||
"metadata":{
|
||||
"name":"om-frontendapi",
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "frontend"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"replicas":1,
|
||||
"selector":{
|
||||
"matchLabels":{
|
||||
"app":"openmatch",
|
||||
"component": "frontend"
|
||||
}
|
||||
},
|
||||
"template":{
|
||||
"metadata":{
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "frontend"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"containers":[
|
||||
{
|
||||
"name":"om-frontendapi",
|
||||
"image":"gcr.io/open-match-public-images/openmatch-frontendapi:dev",
|
||||
"imagePullPolicy":"Always",
|
||||
"ports": [
|
||||
{
|
||||
"name": "grpc",
|
||||
"containerPort": 50504
|
||||
},
|
||||
{
|
||||
"name": "metrics",
|
||||
"containerPort": 9555
|
||||
}
|
||||
],
|
||||
"resources":{
|
||||
"requests":{
|
||||
"memory":"100Mi",
|
||||
"cpu":"100m"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
deployments/k8s/frontendapi_deployment.yaml
Normal file
32
deployments/k8s/frontendapi_deployment.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: om-frontendapi
|
||||
labels:
|
||||
app: openmatch
|
||||
component: frontend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: openmatch
|
||||
component: frontend
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: openmatch
|
||||
component: frontend
|
||||
spec:
|
||||
containers:
|
||||
- name: om-frontendapi
|
||||
image: gcr.io/open-match-public-images/openmatch-frontendapi:dev
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: grpc
|
||||
containerPort: 50504
|
||||
- name: metrics
|
||||
containerPort: 9555
|
||||
resources:
|
||||
requests:
|
||||
memory: 100Mi
|
||||
cpu: 100m
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "om-frontendapi"
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app": "openmatch",
|
||||
"component": "frontend"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 50504,
|
||||
"targetPort": "grpc"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
12
deployments/k8s/frontendapi_service.yaml
Normal file
12
deployments/k8s/frontendapi_service.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: om-frontendapi
|
||||
spec:
|
||||
selector:
|
||||
app: openmatch
|
||||
component: frontend
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 50504
|
||||
targetPort: grpc
|
@ -1,27 +0,0 @@
|
||||
{
|
||||
"apiVersion": "monitoring.coreos.com/v1",
|
||||
"kind": "ServiceMonitor",
|
||||
"metadata": {
|
||||
"name": "openmatch-metrics",
|
||||
"labels": {
|
||||
"app": "openmatch",
|
||||
"agent": "opencensus",
|
||||
"destination": "prometheus"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app": "openmatch",
|
||||
"agent": "opencensus",
|
||||
"destination": "prometheus"
|
||||
}
|
||||
},
|
||||
"endpoints": [
|
||||
{
|
||||
"port": "metrics",
|
||||
"interval": "10s"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
17
deployments/k8s/metrics_servicemonitor.yaml
Normal file
17
deployments/k8s/metrics_servicemonitor.yaml
Normal file
@ -0,0 +1,17 @@
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: openmatch-metrics
|
||||
labels:
|
||||
app: openmatch
|
||||
agent: opencensus
|
||||
destination: prometheus
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: openmatch
|
||||
agent: opencensus
|
||||
destination: prometheus
|
||||
endpoints:
|
||||
- port: metrics
|
||||
interval: 10s
|
@ -1,78 +0,0 @@
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "om-frontend-metrics",
|
||||
"labels": {
|
||||
"app": "openmatch",
|
||||
"component": "frontend",
|
||||
"agent": "opencensus",
|
||||
"destination": "prometheus"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app": "openmatch",
|
||||
"component": "frontend"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "metrics",
|
||||
"targetPort": 9555,
|
||||
"port": 19555
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "om-backend-metrics",
|
||||
"labels": {
|
||||
"app": "openmatch",
|
||||
"component": "backend",
|
||||
"agent": "opencensus",
|
||||
"destination": "prometheus"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app": "openmatch",
|
||||
"component": "backend"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "metrics",
|
||||
"targetPort": 9555,
|
||||
"port": 29555
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "om-mmforc-metrics",
|
||||
"labels": {
|
||||
"app": "openmatch",
|
||||
"component": "mmforc",
|
||||
"agent": "opencensus",
|
||||
"destination": "prometheus"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app": "openmatch",
|
||||
"component": "mmforc"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"name": "metrics",
|
||||
"targetPort": 9555,
|
||||
"port": 39555
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
54
deployments/k8s/metrics_services.yaml
Normal file
54
deployments/k8s/metrics_services.yaml
Normal file
@ -0,0 +1,54 @@
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: om-frontend-metrics
|
||||
labels:
|
||||
app: openmatch
|
||||
component: frontend
|
||||
agent: opencensus
|
||||
destination: prometheus
|
||||
spec:
|
||||
selector:
|
||||
app: openmatch
|
||||
component: frontend
|
||||
ports:
|
||||
- name: metrics
|
||||
targetPort: 9555
|
||||
port: 19555
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: om-backend-metrics
|
||||
labels:
|
||||
app: openmatch
|
||||
component: backend
|
||||
agent: opencensus
|
||||
destination: prometheus
|
||||
spec:
|
||||
selector:
|
||||
app: openmatch
|
||||
component: backend
|
||||
ports:
|
||||
- name: metrics
|
||||
targetPort: 9555
|
||||
port: 29555
|
||||
---
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: om-mmforc-metrics
|
||||
labels:
|
||||
app: openmatch
|
||||
component: mmforc
|
||||
agent: opencensus
|
||||
destination: prometheus
|
||||
spec:
|
||||
selector:
|
||||
app: openmatch
|
||||
component: mmforc
|
||||
ports:
|
||||
- name: metrics
|
||||
targetPort: 9555
|
||||
port: 39555
|
@ -1,59 +0,0 @@
|
||||
{
|
||||
"apiVersion":"extensions/v1beta1",
|
||||
"kind":"Deployment",
|
||||
"metadata":{
|
||||
"name":"om-mmforc",
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "mmforc"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"replicas":1,
|
||||
"selector":{
|
||||
"matchLabels":{
|
||||
"app":"openmatch",
|
||||
"component": "mmforc"
|
||||
}
|
||||
},
|
||||
"template":{
|
||||
"metadata":{
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "mmforc"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"containers":[
|
||||
{
|
||||
"name":"om-mmforc",
|
||||
"image":"gcr.io/open-match-public-images/openmatch-mmforc:dev",
|
||||
"imagePullPolicy":"Always",
|
||||
"ports": [
|
||||
{
|
||||
"name": "metrics",
|
||||
"containerPort":9555
|
||||
}
|
||||
],
|
||||
"resources":{
|
||||
"requests":{
|
||||
"memory":"100Mi",
|
||||
"cpu":"100m"
|
||||
}
|
||||
},
|
||||
"env":[
|
||||
{
|
||||
"name":"METADATA_NAMESPACE",
|
||||
"valueFrom": {
|
||||
"fieldRef": {
|
||||
"fieldPath": "metadata.namespace"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
deployments/k8s/mmforc_deployment.yaml
Normal file
35
deployments/k8s/mmforc_deployment.yaml
Normal file
@ -0,0 +1,35 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: om-mmforc
|
||||
labels:
|
||||
app: openmatch
|
||||
component: mmforc
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: openmatch
|
||||
component: mmforc
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: openmatch
|
||||
component: mmforc
|
||||
spec:
|
||||
containers:
|
||||
- name: om-mmforc
|
||||
image: gcr.io/open-match-public-images/openmatch-mmforc:dev
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: metrics
|
||||
containerPort: 9555
|
||||
resources:
|
||||
requests:
|
||||
memory: 100Mi
|
||||
cpu: 100m
|
||||
env:
|
||||
- name: METADATA_NAMESPACE
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: metadata.namespace
|
@ -1,19 +0,0 @@
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1beta1",
|
||||
"kind": "ClusterRoleBinding",
|
||||
"metadata": {
|
||||
"name": "mmf-sa"
|
||||
},
|
||||
"subjects": [
|
||||
{
|
||||
"kind": "ServiceAccount",
|
||||
"name": "default",
|
||||
"namespace": "default"
|
||||
}
|
||||
],
|
||||
"roleRef": {
|
||||
"kind": "ClusterRole",
|
||||
"name": "cluster-admin",
|
||||
"apiGroup": "rbac.authorization.k8s.io"
|
||||
}
|
||||
}
|
12
deployments/k8s/mmforc_serviceaccount.yaml
Normal file
12
deployments/k8s/mmforc_serviceaccount.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: mmf-sa
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: default
|
||||
namespace: default
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
apiGroup: rbac.authorization.k8s.io
|
@ -1,53 +0,0 @@
|
||||
{
|
||||
"apiVersion":"extensions/v1beta1",
|
||||
"kind":"Deployment",
|
||||
"metadata":{
|
||||
"name":"om-mmlogicapi",
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "mmlogic"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"replicas":1,
|
||||
"selector":{
|
||||
"matchLabels":{
|
||||
"app":"openmatch",
|
||||
"component": "mmlogic"
|
||||
}
|
||||
},
|
||||
"template":{
|
||||
"metadata":{
|
||||
"labels":{
|
||||
"app":"openmatch",
|
||||
"component": "mmlogic"
|
||||
}
|
||||
},
|
||||
"spec":{
|
||||
"containers":[
|
||||
{
|
||||
"name":"om-mmlogic",
|
||||
"image":"gcr.io/open-match-public-images/openmatch-mmlogicapi:dev",
|
||||
"imagePullPolicy":"Always",
|
||||
"ports": [
|
||||
{
|
||||
"name": "grpc",
|
||||
"containerPort": 50503
|
||||
},
|
||||
{
|
||||
"name": "metrics",
|
||||
"containerPort": 9555
|
||||
}
|
||||
],
|
||||
"resources":{
|
||||
"requests":{
|
||||
"memory":"100Mi",
|
||||
"cpu":"100m"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
deployments/k8s/mmlogicapi_deployment.yaml
Normal file
32
deployments/k8s/mmlogicapi_deployment.yaml
Normal file
@ -0,0 +1,32 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: om-mmlogicapi
|
||||
labels:
|
||||
app: openmatch
|
||||
component: mmlogic
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: openmatch
|
||||
component: mmlogic
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: openmatch
|
||||
component: mmlogic
|
||||
spec:
|
||||
containers:
|
||||
- name: om-mmlogic
|
||||
image: gcr.io/open-match-public-images/openmatch-mmlogicapi:dev
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: grpc
|
||||
containerPort: 50503
|
||||
- name: metrics
|
||||
containerPort: 9555
|
||||
resources:
|
||||
requests:
|
||||
memory: 100Mi
|
||||
cpu: 100m
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "om-mmlogicapi"
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app": "openmatch",
|
||||
"component": "mmlogic"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 50503,
|
||||
"targetPort": "grpc"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
12
deployments/k8s/mmlogicapi_service.yaml
Normal file
12
deployments/k8s/mmlogicapi_service.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: om-mmlogicapi
|
||||
spec:
|
||||
selector:
|
||||
app: openmatch
|
||||
component: mmlogic
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 50503
|
||||
targetPort: grpc
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"apiVersion": "monitoring.coreos.com/v1",
|
||||
"kind": "Prometheus",
|
||||
"metadata": {
|
||||
"name": "prometheus"
|
||||
},
|
||||
"spec": {
|
||||
"serviceMonitorSelector": {
|
||||
"matchLabels": {
|
||||
"app": "openmatch"
|
||||
}
|
||||
},
|
||||
"serviceAccountName": "prometheus",
|
||||
"resources": {
|
||||
"requests": {
|
||||
"memory": "400Mi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
12
deployments/k8s/prometheus.yaml
Normal file
12
deployments/k8s/prometheus.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: Prometheus
|
||||
metadata:
|
||||
name: prometheus
|
||||
spec:
|
||||
serviceMonitorSelector:
|
||||
matchLabels:
|
||||
app: openmatch
|
||||
serviceAccountName: prometheus
|
||||
resources:
|
||||
requests:
|
||||
memory: 400Mi
|
@ -1,266 +0,0 @@
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1beta1",
|
||||
"kind": "ClusterRoleBinding",
|
||||
"metadata": {
|
||||
"name": "prometheus-operator"
|
||||
},
|
||||
"roleRef": {
|
||||
"apiGroup": "rbac.authorization.k8s.io",
|
||||
"kind": "ClusterRole",
|
||||
"name": "prometheus-operator"
|
||||
},
|
||||
"subjects": [
|
||||
{
|
||||
"kind": "ServiceAccount",
|
||||
"name": "prometheus-operator",
|
||||
"namespace": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ServiceAccount",
|
||||
"metadata": {
|
||||
"name": "prometheus"
|
||||
}
|
||||
}
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1beta1",
|
||||
"kind": "ClusterRole",
|
||||
"metadata": {
|
||||
"name": "prometheus"
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"nodes",
|
||||
"services",
|
||||
"endpoints",
|
||||
"pods"
|
||||
],
|
||||
"verbs": [
|
||||
"get",
|
||||
"list",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"configmaps"
|
||||
],
|
||||
"verbs": [
|
||||
"get"
|
||||
]
|
||||
},
|
||||
{
|
||||
"nonResourceURLs": [
|
||||
"/metrics"
|
||||
],
|
||||
"verbs": [
|
||||
"get"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1beta1",
|
||||
"kind": "ClusterRoleBinding",
|
||||
"metadata": {
|
||||
"name": "prometheus"
|
||||
},
|
||||
"roleRef": {
|
||||
"apiGroup": "rbac.authorization.k8s.io",
|
||||
"kind": "ClusterRole",
|
||||
"name": "prometheus"
|
||||
},
|
||||
"subjects": [
|
||||
{
|
||||
"kind": "ServiceAccount",
|
||||
"name": "prometheus",
|
||||
"namespace": "default"
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"apiVersion": "rbac.authorization.k8s.io/v1beta1",
|
||||
"kind": "ClusterRole",
|
||||
"metadata": {
|
||||
"name": "prometheus-operator"
|
||||
},
|
||||
"rules": [
|
||||
{
|
||||
"apiGroups": [
|
||||
"extensions"
|
||||
],
|
||||
"resources": [
|
||||
"thirdpartyresources"
|
||||
],
|
||||
"verbs": [
|
||||
"*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
"apiextensions.k8s.io"
|
||||
],
|
||||
"resources": [
|
||||
"customresourcedefinitions"
|
||||
],
|
||||
"verbs": [
|
||||
"*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
"monitoring.coreos.com"
|
||||
],
|
||||
"resources": [
|
||||
"alertmanagers",
|
||||
"prometheuses",
|
||||
"prometheuses/finalizers",
|
||||
"servicemonitors"
|
||||
],
|
||||
"verbs": [
|
||||
"*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
"apps"
|
||||
],
|
||||
"resources": [
|
||||
"statefulsets"
|
||||
],
|
||||
"verbs": [
|
||||
"*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"configmaps",
|
||||
"secrets"
|
||||
],
|
||||
"verbs": [
|
||||
"*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"pods"
|
||||
],
|
||||
"verbs": [
|
||||
"list",
|
||||
"delete"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"services",
|
||||
"endpoints"
|
||||
],
|
||||
"verbs": [
|
||||
"get",
|
||||
"create",
|
||||
"update"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"nodes"
|
||||
],
|
||||
"verbs": [
|
||||
"list",
|
||||
"watch"
|
||||
]
|
||||
},
|
||||
{
|
||||
"apiGroups": [
|
||||
""
|
||||
],
|
||||
"resources": [
|
||||
"namespaces"
|
||||
],
|
||||
"verbs": [
|
||||
"list"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ServiceAccount",
|
||||
"metadata": {
|
||||
"name": "prometheus-operator"
|
||||
}
|
||||
}
|
||||
{
|
||||
"apiVersion": "extensions/v1beta1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"k8s-app": "prometheus-operator"
|
||||
},
|
||||
"name": "prometheus-operator"
|
||||
},
|
||||
"spec": {
|
||||
"replicas": 1,
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"k8s-app": "prometheus-operator"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"args": [
|
||||
"--kubelet-service=kube-system/kubelet",
|
||||
"--config-reloader-image=quay.io/coreos/configmap-reload:v0.0.1"
|
||||
],
|
||||
"image": "quay.io/coreos/prometheus-operator:v0.17.0",
|
||||
"name": "prometheus-operator",
|
||||
"ports": [
|
||||
{
|
||||
"containerPort": 8080,
|
||||
"name": "http"
|
||||
}
|
||||
],
|
||||
"resources": {
|
||||
"limits": {
|
||||
"cpu": "200m",
|
||||
"memory": "100Mi"
|
||||
},
|
||||
"requests": {
|
||||
"cpu": "100m",
|
||||
"memory": "50Mi"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"securityContext": {
|
||||
"runAsNonRoot": true,
|
||||
"runAsUser": 65534
|
||||
},
|
||||
"serviceAccountName": "prometheus-operator"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
166
deployments/k8s/prometheus_operator.yaml
Normal file
166
deployments/k8s/prometheus_operator.yaml
Normal file
@ -0,0 +1,166 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: prometheus-operator
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: prometheus-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: prometheus-operator
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: prometheus
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: prometheus
|
||||
rules:
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- nodes
|
||||
- services
|
||||
- endpoints
|
||||
- pods
|
||||
verbs:
|
||||
- get
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- configmaps
|
||||
verbs:
|
||||
- get
|
||||
- nonResourceURLs:
|
||||
- "/metrics"
|
||||
verbs:
|
||||
- get
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: prometheus
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: prometheus
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: prometheus
|
||||
namespace: default
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: prometheus-operator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- extensions
|
||||
resources:
|
||||
- thirdpartyresources
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- apiextensions.k8s.io
|
||||
resources:
|
||||
- customresourcedefinitions
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- monitoring.coreos.com
|
||||
resources:
|
||||
- alertmanagers
|
||||
- prometheuses
|
||||
- prometheuses/finalizers
|
||||
- servicemonitors
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- apps
|
||||
resources:
|
||||
- statefulsets
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- configmaps
|
||||
- secrets
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- pods
|
||||
verbs:
|
||||
- list
|
||||
- delete
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- services
|
||||
- endpoints
|
||||
verbs:
|
||||
- get
|
||||
- create
|
||||
- update
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- nodes
|
||||
verbs:
|
||||
- list
|
||||
- watch
|
||||
- apiGroups:
|
||||
- ''
|
||||
resources:
|
||||
- namespaces
|
||||
verbs:
|
||||
- list
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: prometheus-operator
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: prometheus-operator
|
||||
name: prometheus-operator
|
||||
spec:
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: prometheus-operator
|
||||
spec:
|
||||
containers:
|
||||
- args:
|
||||
- "--kubelet-service=kube-system/kubelet"
|
||||
- "--config-reloader-image=quay.io/coreos/configmap-reload:v0.0.1"
|
||||
image: quay.io/coreos/prometheus-operator:v0.17.0
|
||||
name: prometheus-operator
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
resources:
|
||||
limits:
|
||||
cpu: 200m
|
||||
memory: 100Mi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 50Mi
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65534
|
||||
serviceAccountName: prometheus-operator
|
@ -1,22 +0,0 @@
|
||||
{
|
||||
"apiVersion": "v1",
|
||||
"kind": "Service",
|
||||
"metadata": {
|
||||
"name": "prometheus"
|
||||
},
|
||||
"spec": {
|
||||
"type": "NodePort",
|
||||
"ports": [
|
||||
{
|
||||
"name": "web",
|
||||
"nodePort": 30900,
|
||||
"port": 9090,
|
||||
"protocol": "TCP",
|
||||
"targetPort": "web"
|
||||
}
|
||||
],
|
||||
"selector": {
|
||||
"prometheus": "prometheus"
|
||||
}
|
||||
}
|
||||
}
|
14
deployments/k8s/prometheus_service.yaml
Normal file
14
deployments/k8s/prometheus_service.yaml
Normal file
@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: prometheus
|
||||
spec:
|
||||
type: NodePort
|
||||
ports:
|
||||
- name: web
|
||||
nodePort: 30900
|
||||
port: 9090
|
||||
protocol: TCP
|
||||
targetPort: web
|
||||
selector:
|
||||
prometheus: prometheus
|
@ -1,38 +0,0 @@
|
||||
{
|
||||
"apiVersion": "extensions/v1beta1",
|
||||
"kind": "Deployment",
|
||||
"metadata": {
|
||||
"name": "redis-master"
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"matchLabels": {
|
||||
"app": "mm",
|
||||
"tier": "storage"
|
||||
}
|
||||
},
|
||||
"replicas": 1,
|
||||
"template": {
|
||||
"metadata": {
|
||||
"labels": {
|
||||
"app": "mm",
|
||||
"tier": "storage"
|
||||
}
|
||||
},
|
||||
"spec": {
|
||||
"containers": [
|
||||
{
|
||||
"name": "redis-master",
|
||||
"image": "redis:4.0.11",
|
||||
"ports": [
|
||||
{
|
||||
"name": "redis",
|
||||
"containerPort": 6379
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
deployments/k8s/redis_deployment.yaml
Normal file
22
deployments/k8s/redis_deployment.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: redis-master
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mm
|
||||
tier: storage
|
||||
replicas: 1
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mm
|
||||
tier: storage
|
||||
spec:
|
||||
containers:
|
||||
- name: redis-master
|
||||
image: redis:4.0.11
|
||||
ports:
|
||||
- name: redis
|
||||
containerPort: 6379
|
@ -1,20 +0,0 @@
|
||||
{
|
||||
"kind": "Service",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "redis"
|
||||
},
|
||||
"spec": {
|
||||
"selector": {
|
||||
"app": "mm",
|
||||
"tier": "storage"
|
||||
},
|
||||
"ports": [
|
||||
{
|
||||
"protocol": "TCP",
|
||||
"port": 6379,
|
||||
"targetPort": "redis"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
12
deployments/k8s/redis_service.yaml
Normal file
12
deployments/k8s/redis_service.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
kind: Service
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: redis
|
||||
spec:
|
||||
selector:
|
||||
app: mm
|
||||
tier: storage
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 6379
|
||||
targetPort: redis
|
@ -1,3 +1,7 @@
|
||||
# Development Guide
|
||||
|
||||
This doc explains how to setup a development environment so you can get started contributing to Open Match. If you instead want to write a matchmaker that _uses_ Open Match, you probably want to read the [User Guide](user_guide.md).
|
||||
|
||||
# Compiling from source
|
||||
|
||||
All components of Open Match produce (Linux) Docker container images as artifacts, and there are included `Dockerfile`s for each. [Google Cloud Platform Cloud Build](https://cloud.google.com/cloud-build/docs/) users will also find `cloudbuild.yaml` files for each component in their respective directories. Note that most of them build from an 'base' image called `openmatch-devbase`. You can find a `Dockerfile` and `cloudbuild_base.yaml` file for this in the repository root. Build it first!
|
||||
@ -11,11 +15,11 @@ Note: Although Google Cloud Platform includes some free usage, you may incur cha
|
||||
**NOTE**: Before starting with this guide, you'll need to update all the URIs from the tutorial's gcr.io container image registry with the URI for your own image registry. If you are using the gcr.io registry on GCP, the default URI is `gcr.io/<PROJECT_NAME>`. Here's an example command in Linux to do the replacement for you this (replace YOUR_REGISTRY_URI with your URI, this should be run from the repository root directory):
|
||||
```
|
||||
# Linux
|
||||
egrep -lR 'open-match-public-images' . | xargs sed -i -e 's|open-match-public-images|<PROJECT_NAME>|g'
|
||||
egrep -lR 'matchmaker-dev-201405' . | xargs sed -i -e 's|matchmaker-dev-201405|<PROJECT_NAME>|g'
|
||||
```
|
||||
```
|
||||
# Mac OS, you can delete the .backup files after if all looks good
|
||||
egrep -lR 'open-match-public-images' . | xargs sed -i'.backup' -e 's|open-match-public-images|<PROJECT_NAME>|g'
|
||||
egrep -lR 'matchmaker-dev-201405' . | xargs sed -i'.backup' -e 's|matchmaker-dev-201405|<PROJECT_NAME>|g'
|
||||
```
|
||||
|
||||
## Example of building using Google Cloud Builder
|
||||
@ -42,15 +46,15 @@ The [Quickstart for Docker](https://cloud.google.com/cloud-build/docs/quickstart
|
||||
(your registry name will be different)
|
||||
```
|
||||
NAME
|
||||
gcr.io/open-match-public-images/openmatch-backendapi
|
||||
gcr.io/open-match-public-images/openmatch-devbase
|
||||
gcr.io/open-match-public-images/openmatch-evaluator
|
||||
gcr.io/open-match-public-images/openmatch-frontendapi
|
||||
gcr.io/open-match-public-images/openmatch-mmf-golang-manual-simple
|
||||
gcr.io/open-match-public-images/openmatch-mmf-php-mmlogic-simple
|
||||
gcr.io/open-match-public-images/openmatch-mmf-py3-mmlogic-simple
|
||||
gcr.io/open-match-public-images/openmatch-mmforc
|
||||
gcr.io/open-match-public-images/openmatch-mmlogicapi
|
||||
gcr.io/matchmaker-dev-201405/openmatch-backendapi
|
||||
gcr.io/matchmaker-dev-201405/openmatch-devbase
|
||||
gcr.io/matchmaker-dev-201405/openmatch-evaluator
|
||||
gcr.io/matchmaker-dev-201405/openmatch-frontendapi
|
||||
gcr.io/matchmaker-dev-201405/openmatch-mmf-golang-manual-simple
|
||||
gcr.io/matchmaker-dev-201405/openmatch-mmf-php-mmlogic-simple
|
||||
gcr.io/matchmaker-dev-201405/openmatch-mmf-py3-mmlogic-simple
|
||||
gcr.io/matchmaker-dev-201405/openmatch-mmforc
|
||||
gcr.io/matchmaker-dev-201405/openmatch-mmlogicapi
|
||||
```
|
||||
## Example of starting a GKE cluster
|
||||
|
||||
@ -76,24 +80,24 @@ The rest of this guide assumes you have a cluster (example is using GKE, but wor
|
||||
|
||||
* Start a copy of redis and a service in front of it:
|
||||
```
|
||||
kubectl apply -f redis_deployment.json
|
||||
kubectl apply -f redis_service.json
|
||||
kubectl apply -f redis_deployment.yaml
|
||||
kubectl apply -f redis_service.yaml
|
||||
```
|
||||
* Run the **core components**: the frontend API, the backend API, the matchmaker function orchestrator (MMFOrc), and the matchmaking logic API.
|
||||
**NOTE** In order to kick off jobs, the matchmaker function orchestrator needs a service account with permission to administer the cluster. This should be updated to have min required perms before launch, this is pretty permissive but acceptable for closed testing:
|
||||
```
|
||||
kubectl apply -f backendapi_deployment.json
|
||||
kubectl apply -f backendapi_service.json
|
||||
kubectl apply -f frontendapi_deployment.json
|
||||
kubectl apply -f frontendapi_service.json
|
||||
kubectl apply -f mmforc_deployment.json
|
||||
kubectl apply -f mmforc_serviceaccount.json
|
||||
kubectl apply -f mmlogicapi_deployment.json
|
||||
kubectl apply -f mmlogicapi_service.json
|
||||
kubectl apply -f backendapi_deployment.yaml
|
||||
kubectl apply -f backendapi_service.yaml
|
||||
kubectl apply -f frontendapi_deployment.yaml
|
||||
kubectl apply -f frontendapi_service.yaml
|
||||
kubectl apply -f mmforc_deployment.yaml
|
||||
kubectl apply -f mmforc_serviceaccount.yaml
|
||||
kubectl apply -f mmlogicapi_deployment.yaml
|
||||
kubectl apply -f mmlogicapi_service.yaml
|
||||
```
|
||||
* [optional, but recommended] Configure the OpenCensus metrics services:
|
||||
```
|
||||
kubectl apply -f metrics_services.json
|
||||
kubectl apply -f metrics_services.yaml
|
||||
```
|
||||
* [optional] Trying to apply the Kubernetes Prometheus Operator resource definition files without a cluster-admin rolebinding on GKE doesn't work without running the following command first. See https://github.com/coreos/prometheus-operator/issues/357
|
||||
```
|
||||
@ -102,10 +106,10 @@ The rest of this guide assumes you have a cluster (example is using GKE, but wor
|
||||
* [optional, uses beta software] If using Prometheus as your metrics gathering backend, configure the [Prometheus Kubernetes Operator](https://github.com/coreos/prometheus-operator):
|
||||
|
||||
```
|
||||
kubectl apply -f prometheus_operator.json
|
||||
kubectl apply -f prometheus.json
|
||||
kubectl apply -f prometheus_service.json
|
||||
kubectl apply -f metrics_servicemonitor.json
|
||||
kubectl apply -f prometheus_operator.yaml
|
||||
kubectl apply -f prometheus.yaml
|
||||
kubectl apply -f prometheus_service.yaml
|
||||
kubectl apply -f metrics_servicemonitor.yaml
|
||||
```
|
||||
You should now be able to see the core component pods running using a `kubectl get pods`, and the core component metrics in the Prometheus Web UI by running `kubectl proxy <PROMETHEUS_POD_NAME> 9090:9090` in your local shell, then opening http://localhost:9090/targets in your browser to see which services Prometheus is collecting from.
|
||||
|
||||
|
@ -11,7 +11,12 @@ All the usual guidance around hardening and securing Kubernetes are applicable t
|
||||
* Note that the default MMForc process has cluster management permissions by default. Before moving to production, you should create a role with only access to create kubernetes jobs and configure the MMForc to use it.
|
||||
### Kubernetes Jobs (MMFOrc)
|
||||
The 0.3.0 MMFOrc component runs your MMFs as Kubernetes Jobs. You should periodically delete these jobs to keep the cluster running smoothly. How often you need to delete them is dependant on how many you are running. There are a number of open source solutions to do this for you. ***Note that once you delete the job, you won't have access to that job's logs anymore unless you're sending your logs from kubernetes to a log aggregator like Google Stackdriver. This can make it a challenge to troubleshoot issues***
|
||||
### CPU and Memory limits
|
||||
For any production Kubernetes deployment, it is good practice to profile your processes and select [resource limits and requests](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) according to your results. For example, you'll likely want to set adequate resource requests based on your expected player base and some load testing for the Redis state storage pods. This will help Kubernetes avoid scheduling other intensive processes on the same underlying node and keep you from running into resource contention issues. Another example might be an MMF with a particularly large memory or CPU footprint - maybe you have one that searches a lot of players for a potential match. This would be a good candidate for resource limits and requests in Kubernetes to both ensure it gets the CPU and RAM it needs to complete quickly, and to make sure it's not scheduled alongside another intensive Kubernetes pod.
|
||||
### State storage
|
||||
The default state storage for Open Match is a _single instance_ of Redis. Although it _is_ possible to go to production with this as the solution if you're willing to accept the potential downsides, for most deployments, a HA Redis configuration would better fit your needs. An example YAML file for creating a [self-healing HA Redis deployment on Kubernetes](../install/yaml/01-redis-failover.yaml) is available. Regardless of which configuation you use, it is probably a good idea to put some [resource requests](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/) in your Kubernetes resource definition as mentioned above.
|
||||
|
||||
You can find more discussion in the [state storage readme doc](../internal/statestorage/redis/README.md).
|
||||
## Open Match config
|
||||
Debug logging and the extra debug code paths should be disabled in the `config/matchmaker_config.json` file (as of the time of this writing, 0.3.0).
|
||||
|
||||
|
16
examples/backendclient/Dockerfile
Executable file → Normal file
16
examples/backendclient/Dockerfile
Executable file → Normal file
@ -1,8 +1,10 @@
|
||||
#FROM golang:1.10.3 as builder
|
||||
FROM gcr.io/open-match-public-images/openmatch-base:dev as builder
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/examples/backendclient
|
||||
COPY ./ ./
|
||||
RUN go get -d -v
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o backendclient .
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
CMD ["./backendclient"]
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/examples/backendclient/
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo .
|
||||
|
||||
FROM gcr.io/distroless/static
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/examples/backendclient/backendclient .
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/examples/backendclient/profiles profiles
|
||||
|
||||
ENTRYPOINT ["/backendclient"]
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
backend "github.com/GoogleCloudPlatform/open-match/internal/pb"
|
||||
"github.com/tidwall/gjson"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
func bytesToString(data []byte) string {
|
||||
@ -125,7 +126,12 @@ func main() {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading stream for ListMatches(_) = _, %v", err)
|
||||
stat, ok := status.FromError(err)
|
||||
if ok {
|
||||
log.Printf("Error reading stream for ListMatches() returned status: %s %s", stat.Code().String(), stat.Message())
|
||||
} else {
|
||||
log.Printf("Error reading stream for ListMatches() returned status: %s", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
@ -154,7 +160,13 @@ func main() {
|
||||
log.Printf("Waiting for matches...")
|
||||
_, err = client.CreateAssignments(context.Background(), assign)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
stat, ok := status.FromError(err)
|
||||
if ok {
|
||||
log.Printf("Error reading stream for ListMatches() returned status: %s %s", stat.Code().String(), stat.Message())
|
||||
} else {
|
||||
log.Printf("Error reading stream for ListMatches() returned status: %s", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
log.Println("Success! Not deleting assignments [demo mode].")
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
# Golang application builder steps
|
||||
FROM gcr.io/open-match-public-images/openmatch-base:dev as builder
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/examples/evaluators/golang/simple
|
||||
COPY . .
|
||||
RUN go get -d -v
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/examples/evaluators/golang/simple/
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo .
|
||||
|
||||
#FROM scratch
|
||||
#COPY --from=builder /go/src/github.com/GoogleCloudPlatform/mmfstub/mmfstub mmfstub
|
||||
ENTRYPOINT ["./simple"]
|
||||
FROM gcr.io/distroless/static
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/examples/evaluators/golang/simple/simple .
|
||||
|
||||
ENTRYPOINT ["/simple"]
|
||||
|
0
examples/evaluators/golang/simple/cloudbuild.yaml
Executable file → Normal file
0
examples/evaluators/golang/simple/cloudbuild.yaml
Executable file → Normal file
@ -32,7 +32,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/GoogleCloudPlatform/open-match/config"
|
||||
om_messages "github.com/GoogleCloudPlatform/open-match/internal/pb"
|
||||
redishelpers "github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis/redispb"
|
||||
"github.com/gobs/pretty"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
@ -47,30 +49,18 @@ func main() {
|
||||
|
||||
// Read config
|
||||
lgr.Println("Initializing config...")
|
||||
cfg, err := readConfig("matchmaker_config", map[string]interface{}{
|
||||
"REDIS_SERVICE_HOST": "redis",
|
||||
"REDIS_SERVICE_PORT": "6379",
|
||||
"auth": map[string]string{
|
||||
// Read from k8s secret eventually
|
||||
// Probably doesn't need a map, just here for reference
|
||||
"password": "12fa",
|
||||
},
|
||||
})
|
||||
cfg, err := config.Read()
|
||||
if err != nil {
|
||||
panic(nil)
|
||||
}
|
||||
|
||||
// Connect to redis
|
||||
// As per https://www.iana.org/assignments/uri-schemes/prov/redis
|
||||
// redis://user:secret@localhost:6379/0?foo=bar&qux=baz // redis pool docs: https://godoc.org/github.com/gomodule/redigo/redis#Pool
|
||||
redisURL := "redis://" + cfg.GetString("REDIS_SERVICE_HOST") + ":" + cfg.GetString("REDIS_SERVICE_PORT")
|
||||
lgr.Println("Connecting to redis at", redisURL)
|
||||
pool := redis.Pool{
|
||||
MaxIdle: 3,
|
||||
MaxActive: 0,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
Dial: func() (redis.Conn, error) { return redis.DialURL(redisURL) },
|
||||
pool, err := redishelpers.ConnectionPool(cfg)
|
||||
if err != nil {
|
||||
lgr.Fatal(err)
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
redisConn := pool.Get()
|
||||
defer redisConn.Close()
|
||||
|
||||
@ -82,7 +72,7 @@ func main() {
|
||||
|
||||
start := time.Now()
|
||||
|
||||
proposedMatchIds, overloadedPlayers, overloadedMatches, approvedMatches, err := stub(cfg, &pool)
|
||||
proposedMatchIds, overloadedPlayers, overloadedMatches, approvedMatches, err := stub(cfg, pool)
|
||||
overloadedPlayerList, overloadedMatchList, approvedMatchList := generateLists(overloadedPlayers, overloadedMatches, approvedMatches)
|
||||
|
||||
fmt.Println("overloadedPlayers")
|
||||
@ -151,36 +141,6 @@ func chooseMatches(overloaded []int) ([]int, []int, error) {
|
||||
return []int{}, overloaded, nil
|
||||
}
|
||||
|
||||
func readConfig(filename string, defaults map[string]interface{}) (*viper.Viper, error) {
|
||||
/*
|
||||
Examples of redis-related env vars as written by k8s
|
||||
REDIS_SENTINEL_PORT_6379_TCP=tcp://10.55.253.195:6379
|
||||
REDIS_SENTINEL_PORT=tcp://10.55.253.195:6379
|
||||
REDIS_SENTINEL_PORT_6379_TCP_ADDR=10.55.253.195
|
||||
REDIS_SERVICE_PORT=6379
|
||||
REDIS_SENTINEL_PORT_6379_TCP_PORT=6379
|
||||
REDIS_SENTINEL_PORT_6379_TCP_PROTO=tcp
|
||||
REDIS_SERVICE_HOST=10.55.253.195
|
||||
*/
|
||||
v := viper.New()
|
||||
for key, value := range defaults {
|
||||
v.SetDefault(key, value)
|
||||
}
|
||||
v.SetConfigName(filename)
|
||||
v.SetConfigType("json")
|
||||
v.AddConfigPath(".")
|
||||
v.AutomaticEnv()
|
||||
|
||||
// Optional read from config if it exists
|
||||
err := v.ReadInConfig()
|
||||
if err != nil {
|
||||
//lgr.Printf("error when reading config: %v\n", err)
|
||||
//lgr.Println("continuing...")
|
||||
err = nil
|
||||
}
|
||||
return v, err
|
||||
}
|
||||
|
||||
func stub(cfg *viper.Viper, pool *redis.Pool) ([]string, map[string][]int, map[int][]int, map[int]bool, error) {
|
||||
//Init Logger
|
||||
lgr := log.New(os.Stdout, "MMFEvalStub: ", log.LstdFlags)
|
||||
|
@ -1 +0,0 @@
|
||||
../../../../config/matchmaker_config.json
|
1
examples/evaluators/golang/simple/matchmaker_config.yaml
Symbolic link
1
examples/evaluators/golang/simple/matchmaker_config.yaml
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../config/matchmaker_config.yaml
|
@ -1,10 +1,9 @@
|
||||
# Golang application builder steps
|
||||
FROM gcr.io/open-match-public-images/openmatch-base:dev as builder
|
||||
FROM open-match-base-build as builder
|
||||
|
||||
WORKDIR /go/src/github.com/GoogleCloudPlatform/open-match/examples/functions/golang/manual-simple
|
||||
COPY . .
|
||||
RUN go get -d -v
|
||||
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o mmf .
|
||||
|
||||
#FROM scratch
|
||||
#COPY --from=builder /go/src/github.com/GoogleCloudPlatform/mmfstub/mmfstub mmfstub
|
||||
CMD ["./mmf"]
|
||||
FROM gcr.io/distroless/static
|
||||
COPY --from=builder /go/src/github.com/GoogleCloudPlatform/open-match/examples/functions/golang/manual-simple/mmf .
|
||||
|
||||
ENTRYPOINT ["/mmf"]
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/open-match/config"
|
||||
messages "github.com/GoogleCloudPlatform/open-match/internal/pb"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/set"
|
||||
redishelpers "github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis"
|
||||
"github.com/GoogleCloudPlatform/open-match/internal/statestorage/redis/ignorelist"
|
||||
"github.com/gogo/protobuf/jsonpb"
|
||||
"github.com/gomodule/redigo/redis"
|
||||
@ -51,12 +52,17 @@ func main() {
|
||||
// Read config file.
|
||||
cfg := viper.New()
|
||||
cfg, err := config.Read()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// As per https://www.iana.org/assignments/uri-schemes/prov/redis
|
||||
// redis://user:secret@localhost:6379/0?foo=bar&qux=baz
|
||||
redisURL := "redis://" + os.Getenv("REDIS_SERVICE_HOST") + ":" + os.Getenv("REDIS_SERVICE_PORT")
|
||||
fmt.Println("Connecting to Redis at", redisURL)
|
||||
redisConn, err := redis.DialURL(redisURL)
|
||||
pool, err := redishelpers.ConnectionPool(cfg)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer pool.Close()
|
||||
|
||||
redisConn := pool.Get()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -64,7 +70,7 @@ func main() {
|
||||
|
||||
// decrement the number of running MMFs once finished
|
||||
defer func() {
|
||||
fmt.Println("DECR moncurrentMMFs")
|
||||
fmt.Println("DECR concurrentMMFs")
|
||||
_, err = redisConn.Do("DECR", "concurrentMMFs")
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
@ -102,7 +108,7 @@ func main() {
|
||||
// select players
|
||||
const numPlayers = 8
|
||||
// ZRANGE is 0-indexed
|
||||
pools := gjson.Get(profile["properties"], cfg.GetString("jsonkeys.pools"))
|
||||
pools := gjson.Get(profile["properties"], os.Getenv("JSONKEYS_POOLS"))
|
||||
fmt.Println("=========Pools")
|
||||
fmt.Printf("pool.String() = %+v\n", pools.String())
|
||||
|
||||
@ -204,7 +210,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Loop through each roster in the profile and fill in players.
|
||||
rosters := gjson.Get(profile["properties"], cfg.GetString("jsonkeys.rosters"))
|
||||
rosters := gjson.Get(profile["properties"], os.Getenv("JSONKEYS_ROSTERS"))
|
||||
fmt.Println("=========Rosters")
|
||||
fmt.Printf("rosters.String() = %+v\n", rosters.String())
|
||||
|
||||
@ -269,9 +275,9 @@ func main() {
|
||||
// Not enough players, exit.
|
||||
fmt.Println("Not enough players in the pool to fill all player slots in requested roster", rName)
|
||||
fmt.Printf("%+v\n", roster.String())
|
||||
fmt.Println("SET", errorKey, `{"error": "insufficient_players"}`)
|
||||
redisConn.Do("SET", errorKey, `{"error": "insufficient_players"}`)
|
||||
os.Exit(1)
|
||||
fmt.Println("HSET", errorKey, "error", "insufficient_players")
|
||||
redisConn.Do("HSET", errorKey, "error", "insufficient_players")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
}
|
||||
@ -317,7 +323,7 @@ func main() {
|
||||
// for backwards compatibility with backends that haven't been updated to take
|
||||
// advantage of the new rosters field in the MatchObject protobuf message introduced
|
||||
// in 0.2.0.
|
||||
profile["properties"], err = sjson.Set(profile["properties"], cfg.GetString("jsonkeys.rosters"), proposedRosters.String())
|
||||
profile["properties"], err = sjson.Set(profile["properties"], os.Getenv("JSONKEYS_ROSTERS"), proposedRosters.String())
|
||||
profile["properties"] = strings.Replace(profile["properties"], "\\", "", -1)
|
||||
profile["properties"] = strings.Replace(profile["properties"], "]\"", "]", -1)
|
||||
profile["properties"] = strings.Replace(profile["properties"], "\"[", "[", -1)
|
||||
|
@ -1 +0,0 @@
|
||||
../../../../config/matchmaker_config.json
|
1
examples/functions/golang/manual-simple/matchmaker_config.yaml
Symbolic link
1
examples/functions/golang/manual-simple/matchmaker_config.yaml
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../config/matchmaker_config.yaml
|
@ -11,9 +11,11 @@ RUN echo "extension=grpc.so" > /usr/local/etc/php/conf.d/30-grpc.ini
|
||||
RUN pecl install protobuf
|
||||
RUN echo "extension=protobuf.so" > /usr/local/etc/php/conf.d/30-protobuf.ini
|
||||
|
||||
WORKDIR /usr/src/open-match
|
||||
COPY examples/functions/php/mmlogic-simple examples/functions/php/mmlogic-simple
|
||||
COPY config config
|
||||
RUN mkdir -p /usr/src/open-match/examples/functions/php/mmlogic-simple
|
||||
COPY examples/functions/php/mmlogic-simple /usr/src/open-match/examples/functions/php/mmlogic-simple
|
||||
|
||||
# TODO: Remove embedding the config once loading configuration is normalized and this can respect the ConfigMap.
|
||||
COPY config /usr/src/open-match/examples/functions/php/mmlogic-simple/config
|
||||
WORKDIR /usr/src/open-match/examples/functions/php/mmlogic-simple
|
||||
|
||||
RUN composer install
|
@ -10,12 +10,11 @@ function dump_pb_message($msg) {
|
||||
print($msg->serializeToJsonString() . "\n");
|
||||
}
|
||||
|
||||
# Load config file
|
||||
$cfg = json_decode(file_get_contents('matchmaker_config.json'), true);
|
||||
$debug = strtolower(trim(getenv('DEBUG'))) == 'true';
|
||||
|
||||
# Step 2 - Talk to Redis. This example uses the MM Logic API in OM to read/write to/from redis.
|
||||
# Establish grpc channel and make the API client stub
|
||||
$api_conn_info = sprintf('%s:%s', $cfg['api']['mmlogic']['hostname'], $cfg['api']['mmlogic']['port']);
|
||||
$api_conn_info = sprintf('%s:%s', getenv('OM_MMLOGICAPI_SERVICE_HOST'), getenv('OM_MMLOGICAPI_SERVICE_PORT'));
|
||||
|
||||
$mmlogic_api = new Api\MmLogicClient($api_conn_info, [
|
||||
'credentials' => Grpc\ChannelCredentials::createInsecure(),
|
||||
@ -24,8 +23,8 @@ $mmlogic_api = new Api\MmLogicClient($api_conn_info, [
|
||||
# Step 3 - Read the profile written to the Backend API.
|
||||
# Get profile from redis
|
||||
$match_object = new Messages\MatchObject([
|
||||
'id' => getenv('MMF_PROFILE_ID'
|
||||
)]);
|
||||
'id' => getenv('MMF_PROFILE_ID')
|
||||
]);
|
||||
list($profile_pb, $status) = $mmlogic_api->GetProfile($match_object)->wait();
|
||||
dump_pb_message($profile_pb);
|
||||
|
||||
@ -47,7 +46,7 @@ foreach ($profile_pb->getPools() as $empty_pool) {
|
||||
$empty_pool->setStats(new Messages\Stats());
|
||||
}
|
||||
|
||||
if ($cfg['debug']) {
|
||||
if ($debug) {
|
||||
$start = microtime(true);
|
||||
}
|
||||
|
||||
@ -73,7 +72,7 @@ foreach ($profile_pb->getPools() as $empty_pool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($cfg['debug']) {
|
||||
if ($debug) {
|
||||
$end = microtime(true);
|
||||
printf("\n'%s': count %06d | elapsed %0.3f\n", $empty_pool_name, count($player_pools[$empty_pool_name]), $end - $start);
|
||||
}
|
||||
@ -85,8 +84,7 @@ foreach ($profile_pb->getPools() as $empty_pool) {
|
||||
$results = make_matches($profile_dict, $player_pools);
|
||||
#################################################################
|
||||
|
||||
# DEBUG
|
||||
if ($cfg['debug']) {
|
||||
if (debug) {
|
||||
print("======= match_properties\n");
|
||||
var_export($results);
|
||||
}
|
||||
@ -101,7 +99,7 @@ $mo->setPools($profile_pb->getPools());
|
||||
# Access the rosters in dict form within the properties json.
|
||||
# It is stored at the key specified in the config file.
|
||||
$rosters_dict = $results;
|
||||
foreach (explode('.', $cfg['jsonkeys']['rosters']) as $partial_key) {
|
||||
foreach (explode('.', getenv('JSONKEYS_ROSTERS')) as $partial_key) {
|
||||
$rosters_dict = $rosters_dict[$partial_key] ?? [];
|
||||
}
|
||||
|
||||
@ -112,8 +110,7 @@ foreach ($rosters_dict as $roster) {
|
||||
$mo->getRosters() []= $r;
|
||||
}
|
||||
|
||||
#DEBUG: writing to error key prevents evalutor run
|
||||
if ($cfg['debug']) {
|
||||
if ($debug) {
|
||||
print("======== MMF results:\n");
|
||||
dump_pb_message($mo);
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
../../../../config/matchmaker_config.json
|
@ -1,5 +1,4 @@
|
||||
# Golang application builder steps
|
||||
FROM python:3.5.3 as builder
|
||||
FROM python:3.5.3
|
||||
WORKDIR /usr/src/open-match
|
||||
COPY examples/functions/python3/mmlogic-simple examples/functions/python3/mmlogic-simple
|
||||
COPY config config
|
@ -1,18 +1,5 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: api/protobuf-spec/messages.proto
|
||||
#Copyright 2018 Google LLC
|
||||
#Licensed under the Apache License, Version 2.0 (the "License");
|
||||
#you may not use this file except in compliance with the License.
|
||||
#You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#Unless required by applicable law or agreed to in writing, software
|
||||
#distributed under the License is distributed on an "AS IS" BASIS,
|
||||
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#See the License for the specific language governing permissions and
|
||||
#limitations under the License.
|
||||
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
@ -32,64 +19,12 @@ DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
package='messages',
|
||||
syntax='proto3',
|
||||
serialized_options=_b('Z5github.com/GoogleCloudPlatform/open-match/internal/pb'),
|
||||
serialized_pb=_b('\n api/protobuf-spec/messages.proto\x12\x08messages\"\\\n\x07Profile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x12\n\nproperties\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12#\n\x05pools\x18\x04 \x03(\x0b\x32\x14.messages.PlayerPool\"\x84\x01\n\x0bMatchObject\x12\n\n\x02id\x18\x01 \x01(\t\x12\x12\n\nproperties\x18\x02 \x01(\t\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12!\n\x07rosters\x18\x04 \x03(\x0b\x32\x10.messages.Roster\x12#\n\x05pools\x18\x05 \x03(\x0b\x32\x14.messages.PlayerPool\"9\n\x06Roster\x12\x0c\n\x04name\x18\x01 \x01(\t\x12!\n\x07players\x18\x02 \x03(\x0b\x32\x10.messages.Player\"e\n\x06\x46ilter\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tattribute\x18\x02 \x01(\t\x12\x0c\n\x04maxv\x18\x03 \x01(\x03\x12\x0c\n\x04minv\x18\x04 \x01(\x03\x12\x1e\n\x05stats\x18\x05 \x01(\x0b\x32\x0f.messages.Stats\"\'\n\x05Stats\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12\x0f\n\x07\x65lapsed\x18\x02 \x01(\x01\"\x7f\n\nPlayerPool\x12\x0c\n\x04name\x18\x01 \x01(\t\x12!\n\x07\x66ilters\x18\x02 \x03(\x0b\x32\x10.messages.Filter\x12 \n\x06roster\x18\x03 \x01(\x0b\x32\x10.messages.Roster\x12\x1e\n\x05stats\x18\x04 \x01(\x0b\x32\x0f.messages.Stats\"\x90\x01\n\x06Player\x12\n\n\x02id\x18\x01 \x01(\t\x12\x12\n\nproperties\x18\x02 \x01(\t\x12\x0c\n\x04pool\x18\x03 \x01(\t\x12.\n\nattributes\x18\x04 \x03(\x0b\x32\x1a.messages.Player.Attribute\x1a(\n\tAttribute\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03\"(\n\x06Result\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\t\n\x07IlInput\"\x17\n\tTimestamp\x12\n\n\x02ts\x18\x01 \x01(\x03\"+\n\x0e\x43onnectionInfo\x12\x19\n\x11\x63onnection_string\x18\x01 \x01(\t\"c\n\x0b\x41ssignments\x12!\n\x07rosters\x18\x01 \x03(\x0b\x32\x10.messages.Roster\x12\x31\n\x0f\x63onnection_info\x18\x02 \x01(\x0b\x32\x18.messages.ConnectionInfoB7Z5github.com/GoogleCloudPlatform/open-match/internal/pbb\x06proto3')
|
||||
serialized_pb=_b('\n api/protobuf-spec/messages.proto\x12\x08messages\"\x94\x01\n\x0bMatchObject\x12\n\n\x02id\x18\x01 \x01(\t\x12\x12\n\nproperties\x18\x02 \x01(\t\x12\r\n\x05\x65rror\x18\x03 \x01(\t\x12!\n\x07rosters\x18\x04 \x03(\x0b\x32\x10.messages.Roster\x12#\n\x05pools\x18\x05 \x03(\x0b\x32\x14.messages.PlayerPool\x12\x0e\n\x06status\x18\x06 \x01(\t\"9\n\x06Roster\x12\x0c\n\x04name\x18\x01 \x01(\t\x12!\n\x07players\x18\x02 \x03(\x0b\x32\x10.messages.Player\"e\n\x06\x46ilter\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x11\n\tattribute\x18\x02 \x01(\t\x12\x0c\n\x04maxv\x18\x03 \x01(\x03\x12\x0c\n\x04minv\x18\x04 \x01(\x03\x12\x1e\n\x05stats\x18\x05 \x01(\x0b\x32\x0f.messages.Stats\"\'\n\x05Stats\x12\r\n\x05\x63ount\x18\x01 \x01(\x03\x12\x0f\n\x07\x65lapsed\x18\x02 \x01(\x01\"\x7f\n\nPlayerPool\x12\x0c\n\x04name\x18\x01 \x01(\t\x12!\n\x07\x66ilters\x18\x02 \x03(\x0b\x32\x10.messages.Filter\x12 \n\x06roster\x18\x03 \x01(\x0b\x32\x10.messages.Roster\x12\x1e\n\x05stats\x18\x04 \x01(\x0b\x32\x0f.messages.Stats\"\xc3\x01\n\x06Player\x12\n\n\x02id\x18\x01 \x01(\t\x12\x12\n\nproperties\x18\x02 \x01(\t\x12\x0c\n\x04pool\x18\x03 \x01(\t\x12.\n\nattributes\x18\x04 \x03(\x0b\x32\x1a.messages.Player.Attribute\x12\x12\n\nassignment\x18\x05 \x01(\t\x12\x0e\n\x06status\x18\x06 \x01(\t\x12\r\n\x05\x65rror\x18\x07 \x01(\t\x1a(\n\tAttribute\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x03\"(\n\x06Result\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\r\n\x05\x65rror\x18\x02 \x01(\t\"\t\n\x07IlInput\"D\n\x0b\x41ssignments\x12!\n\x07rosters\x18\x01 \x03(\x0b\x32\x10.messages.Roster\x12\x12\n\nassignment\x18\n \x01(\t\"k\n\x07Request\x12\x12\n\nprofile_id\x18\x01 \x01(\t\x12\x13\n\x0bproposal_id\x18\x02 \x01(\t\x12\x12\n\nrequest_id\x18\x03 \x01(\t\x12\x10\n\x08\x65rror_id\x18\x04 \x01(\t\x12\x11\n\ttimestamp\x18\x05 \x01(\t\"[\n\tArguments\x12\"\n\x07request\x18\x01 \x01(\x0b\x32\x11.messages.Request\x12*\n\x0bmatchobject\x18\x02 \x01(\x0b\x32\x15.messages.MatchObjectB7Z5github.com/GoogleCloudPlatform/open-match/internal/pbb\x06proto3')
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
_PROFILE = _descriptor.Descriptor(
|
||||
name='Profile',
|
||||
full_name='messages.Profile',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='id', full_name='messages.Profile.id', index=0,
|
||||
number=1, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='properties', full_name='messages.Profile.properties', index=1,
|
||||
number=2, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='name', full_name='messages.Profile.name', index=2,
|
||||
number=3, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='pools', full_name='messages.Profile.pools', index=3,
|
||||
number=4, type=11, cpp_type=10, label=3,
|
||||
has_default_value=False, default_value=[],
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=46,
|
||||
serialized_end=138,
|
||||
)
|
||||
|
||||
|
||||
_MATCHOBJECT = _descriptor.Descriptor(
|
||||
name='MatchObject',
|
||||
full_name='messages.MatchObject',
|
||||
@ -132,6 +67,13 @@ _MATCHOBJECT = _descriptor.Descriptor(
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='status', full_name='messages.MatchObject.status', index=5,
|
||||
number=6, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
@ -144,8 +86,8 @@ _MATCHOBJECT = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=141,
|
||||
serialized_end=273,
|
||||
serialized_start=47,
|
||||
serialized_end=195,
|
||||
)
|
||||
|
||||
|
||||
@ -182,8 +124,8 @@ _ROSTER = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=275,
|
||||
serialized_end=332,
|
||||
serialized_start=197,
|
||||
serialized_end=254,
|
||||
)
|
||||
|
||||
|
||||
@ -241,8 +183,8 @@ _FILTER = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=334,
|
||||
serialized_end=435,
|
||||
serialized_start=256,
|
||||
serialized_end=357,
|
||||
)
|
||||
|
||||
|
||||
@ -279,8 +221,8 @@ _STATS = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=437,
|
||||
serialized_end=476,
|
||||
serialized_start=359,
|
||||
serialized_end=398,
|
||||
)
|
||||
|
||||
|
||||
@ -331,8 +273,8 @@ _PLAYERPOOL = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=478,
|
||||
serialized_end=605,
|
||||
serialized_start=400,
|
||||
serialized_end=527,
|
||||
)
|
||||
|
||||
|
||||
@ -369,8 +311,8 @@ _PLAYER_ATTRIBUTE = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=712,
|
||||
serialized_end=752,
|
||||
serialized_start=685,
|
||||
serialized_end=725,
|
||||
)
|
||||
|
||||
_PLAYER = _descriptor.Descriptor(
|
||||
@ -408,6 +350,27 @@ _PLAYER = _descriptor.Descriptor(
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='assignment', full_name='messages.Player.assignment', index=4,
|
||||
number=5, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='status', full_name='messages.Player.status', index=5,
|
||||
number=6, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='error', full_name='messages.Player.error', index=6,
|
||||
number=7, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
@ -420,8 +383,8 @@ _PLAYER = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=608,
|
||||
serialized_end=752,
|
||||
serialized_start=530,
|
||||
serialized_end=725,
|
||||
)
|
||||
|
||||
|
||||
@ -458,8 +421,8 @@ _RESULT = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=754,
|
||||
serialized_end=794,
|
||||
serialized_start=727,
|
||||
serialized_end=767,
|
||||
)
|
||||
|
||||
|
||||
@ -482,70 +445,8 @@ _ILINPUT = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=796,
|
||||
serialized_end=805,
|
||||
)
|
||||
|
||||
|
||||
_TIMESTAMP = _descriptor.Descriptor(
|
||||
name='Timestamp',
|
||||
full_name='messages.Timestamp',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='ts', full_name='messages.Timestamp.ts', index=0,
|
||||
number=1, type=3, cpp_type=2, label=1,
|
||||
has_default_value=False, default_value=0,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=807,
|
||||
serialized_end=830,
|
||||
)
|
||||
|
||||
|
||||
_CONNECTIONINFO = _descriptor.Descriptor(
|
||||
name='ConnectionInfo',
|
||||
full_name='messages.ConnectionInfo',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='connection_string', full_name='messages.ConnectionInfo.connection_string', index=0,
|
||||
number=1, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=832,
|
||||
serialized_end=875,
|
||||
serialized_start=769,
|
||||
serialized_end=778,
|
||||
)
|
||||
|
||||
|
||||
@ -564,7 +465,104 @@ _ASSIGNMENTS = _descriptor.Descriptor(
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='connection_info', full_name='messages.Assignments.connection_info', index=1,
|
||||
name='assignment', full_name='messages.Assignments.assignment', index=1,
|
||||
number=10, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=780,
|
||||
serialized_end=848,
|
||||
)
|
||||
|
||||
|
||||
_REQUEST = _descriptor.Descriptor(
|
||||
name='Request',
|
||||
full_name='messages.Request',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='profile_id', full_name='messages.Request.profile_id', index=0,
|
||||
number=1, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='proposal_id', full_name='messages.Request.proposal_id', index=1,
|
||||
number=2, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='request_id', full_name='messages.Request.request_id', index=2,
|
||||
number=3, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='error_id', full_name='messages.Request.error_id', index=3,
|
||||
number=4, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='timestamp', full_name='messages.Request.timestamp', index=4,
|
||||
number=5, type=9, cpp_type=9, label=1,
|
||||
has_default_value=False, default_value=_b("").decode('utf-8'),
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
],
|
||||
extensions=[
|
||||
],
|
||||
nested_types=[],
|
||||
enum_types=[
|
||||
],
|
||||
serialized_options=None,
|
||||
is_extendable=False,
|
||||
syntax='proto3',
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=850,
|
||||
serialized_end=957,
|
||||
)
|
||||
|
||||
|
||||
_ARGUMENTS = _descriptor.Descriptor(
|
||||
name='Arguments',
|
||||
full_name='messages.Arguments',
|
||||
filename=None,
|
||||
file=DESCRIPTOR,
|
||||
containing_type=None,
|
||||
fields=[
|
||||
_descriptor.FieldDescriptor(
|
||||
name='request', full_name='messages.Arguments.request', index=0,
|
||||
number=1, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
is_extension=False, extension_scope=None,
|
||||
serialized_options=None, file=DESCRIPTOR),
|
||||
_descriptor.FieldDescriptor(
|
||||
name='matchobject', full_name='messages.Arguments.matchobject', index=1,
|
||||
number=2, type=11, cpp_type=10, label=1,
|
||||
has_default_value=False, default_value=None,
|
||||
message_type=None, enum_type=None, containing_type=None,
|
||||
@ -582,11 +580,10 @@ _ASSIGNMENTS = _descriptor.Descriptor(
|
||||
extension_ranges=[],
|
||||
oneofs=[
|
||||
],
|
||||
serialized_start=877,
|
||||
serialized_end=976,
|
||||
serialized_start=959,
|
||||
serialized_end=1050,
|
||||
)
|
||||
|
||||
_PROFILE.fields_by_name['pools'].message_type = _PLAYERPOOL
|
||||
_MATCHOBJECT.fields_by_name['rosters'].message_type = _ROSTER
|
||||
_MATCHOBJECT.fields_by_name['pools'].message_type = _PLAYERPOOL
|
||||
_ROSTER.fields_by_name['players'].message_type = _PLAYER
|
||||
@ -597,8 +594,8 @@ _PLAYERPOOL.fields_by_name['stats'].message_type = _STATS
|
||||
_PLAYER_ATTRIBUTE.containing_type = _PLAYER
|
||||
_PLAYER.fields_by_name['attributes'].message_type = _PLAYER_ATTRIBUTE
|
||||
_ASSIGNMENTS.fields_by_name['rosters'].message_type = _ROSTER
|
||||
_ASSIGNMENTS.fields_by_name['connection_info'].message_type = _CONNECTIONINFO
|
||||
DESCRIPTOR.message_types_by_name['Profile'] = _PROFILE
|
||||
_ARGUMENTS.fields_by_name['request'].message_type = _REQUEST
|
||||
_ARGUMENTS.fields_by_name['matchobject'].message_type = _MATCHOBJECT
|
||||
DESCRIPTOR.message_types_by_name['MatchObject'] = _MATCHOBJECT
|
||||
DESCRIPTOR.message_types_by_name['Roster'] = _ROSTER
|
||||
DESCRIPTOR.message_types_by_name['Filter'] = _FILTER
|
||||
@ -607,18 +604,11 @@ DESCRIPTOR.message_types_by_name['PlayerPool'] = _PLAYERPOOL
|
||||
DESCRIPTOR.message_types_by_name['Player'] = _PLAYER
|
||||
DESCRIPTOR.message_types_by_name['Result'] = _RESULT
|
||||
DESCRIPTOR.message_types_by_name['IlInput'] = _ILINPUT
|
||||
DESCRIPTOR.message_types_by_name['Timestamp'] = _TIMESTAMP
|
||||
DESCRIPTOR.message_types_by_name['ConnectionInfo'] = _CONNECTIONINFO
|
||||
DESCRIPTOR.message_types_by_name['Assignments'] = _ASSIGNMENTS
|
||||
DESCRIPTOR.message_types_by_name['Request'] = _REQUEST
|
||||
DESCRIPTOR.message_types_by_name['Arguments'] = _ARGUMENTS
|
||||
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
|
||||
|
||||
Profile = _reflection.GeneratedProtocolMessageType('Profile', (_message.Message,), dict(
|
||||
DESCRIPTOR = _PROFILE,
|
||||
__module__ = 'api.protobuf_spec.messages_pb2'
|
||||
# @@protoc_insertion_point(class_scope:messages.Profile)
|
||||
))
|
||||
_sym_db.RegisterMessage(Profile)
|
||||
|
||||
MatchObject = _reflection.GeneratedProtocolMessageType('MatchObject', (_message.Message,), dict(
|
||||
DESCRIPTOR = _MATCHOBJECT,
|
||||
__module__ = 'api.protobuf_spec.messages_pb2'
|
||||
@ -683,20 +673,6 @@ IlInput = _reflection.GeneratedProtocolMessageType('IlInput', (_message.Message,
|
||||
))
|
||||
_sym_db.RegisterMessage(IlInput)
|
||||
|
||||
Timestamp = _reflection.GeneratedProtocolMessageType('Timestamp', (_message.Message,), dict(
|
||||
DESCRIPTOR = _TIMESTAMP,
|
||||
__module__ = 'api.protobuf_spec.messages_pb2'
|
||||
# @@protoc_insertion_point(class_scope:messages.Timestamp)
|
||||
))
|
||||
_sym_db.RegisterMessage(Timestamp)
|
||||
|
||||
ConnectionInfo = _reflection.GeneratedProtocolMessageType('ConnectionInfo', (_message.Message,), dict(
|
||||
DESCRIPTOR = _CONNECTIONINFO,
|
||||
__module__ = 'api.protobuf_spec.messages_pb2'
|
||||
# @@protoc_insertion_point(class_scope:messages.ConnectionInfo)
|
||||
))
|
||||
_sym_db.RegisterMessage(ConnectionInfo)
|
||||
|
||||
Assignments = _reflection.GeneratedProtocolMessageType('Assignments', (_message.Message,), dict(
|
||||
DESCRIPTOR = _ASSIGNMENTS,
|
||||
__module__ = 'api.protobuf_spec.messages_pb2'
|
||||
@ -704,6 +680,20 @@ Assignments = _reflection.GeneratedProtocolMessageType('Assignments', (_message.
|
||||
))
|
||||
_sym_db.RegisterMessage(Assignments)
|
||||
|
||||
Request = _reflection.GeneratedProtocolMessageType('Request', (_message.Message,), dict(
|
||||
DESCRIPTOR = _REQUEST,
|
||||
__module__ = 'api.protobuf_spec.messages_pb2'
|
||||
# @@protoc_insertion_point(class_scope:messages.Request)
|
||||
))
|
||||
_sym_db.RegisterMessage(Request)
|
||||
|
||||
Arguments = _reflection.GeneratedProtocolMessageType('Arguments', (_message.Message,), dict(
|
||||
DESCRIPTOR = _ARGUMENTS,
|
||||
__module__ = 'api.protobuf_spec.messages_pb2'
|
||||
# @@protoc_insertion_point(class_scope:messages.Arguments)
|
||||
))
|
||||
_sym_db.RegisterMessage(Arguments)
|
||||
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
@ -1,16 +1,3 @@
|
||||
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
||||
#Copyright 2018 Google LLC
|
||||
#Licensed under the Apache License, Version 2.0 (the "License");
|
||||
#you may not use this file except in compliance with the License.
|
||||
#You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#Unless required by applicable law or agreed to in writing, software
|
||||
#distributed under the License is distributed on an "AS IS" BASIS,
|
||||
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#See the License for the specific language governing permissions and
|
||||
#limitations under the License.
|
||||
|
||||
import grpc
|
||||
|
||||
|
@ -1,17 +1,5 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: api/protobuf-spec/mmlogic.proto
|
||||
#Copyright 2018 Google LLC
|
||||
#Licensed under the Apache License, Version 2.0 (the "License");
|
||||
#you may not use this file except in compliance with the License.
|
||||
#You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#Unless required by applicable law or agreed to in writing, software
|
||||
#distributed under the License is distributed on an "AS IS" BASIS,
|
||||
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#See the License for the specific language governing permissions and
|
||||
#limitations under the License.
|
||||
|
||||
import sys
|
||||
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
|
||||
@ -32,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
|
||||
package='api',
|
||||
syntax='proto3',
|
||||
serialized_options=_b('Z5github.com/GoogleCloudPlatform/open-match/internal/pb'),
|
||||
serialized_pb=_b('\n\x1f\x61pi/protobuf-spec/mmlogic.proto\x12\x03\x61pi\x1a api/protobuf-spec/messages.proto2\xf6\x02\n\x07MmLogic\x12<\n\nGetProfile\x12\x15.messages.MatchObject\x1a\x15.messages.MatchObject\"\x00\x12;\n\x0e\x43reateProposal\x12\x15.messages.MatchObject\x1a\x10.messages.Result\"\x00\x12\x33\n\x0bReturnError\x12\x10.messages.Result\x1a\x10.messages.Result\"\x00\x12?\n\rGetPlayerPool\x12\x14.messages.PlayerPool\x1a\x14.messages.PlayerPool\"\x00\x30\x01\x12=\n\x14GetAllIgnoredPlayers\x12\x11.messages.IlInput\x1a\x10.messages.Roster\"\x00\x12;\n\x12ListIgnoredPlayers\x12\x11.messages.IlInput\x1a\x10.messages.Roster\"\x00\x42\x37Z5github.com/GoogleCloudPlatform/open-match/internal/pbb\x06proto3')
|
||||
serialized_pb=_b('\n\x1f\x61pi/protobuf-spec/mmlogic.proto\x12\x03\x61pi\x1a api/protobuf-spec/messages.proto2\xc1\x02\n\x07MmLogic\x12<\n\nGetProfile\x12\x15.messages.MatchObject\x1a\x15.messages.MatchObject\"\x00\x12;\n\x0e\x43reateProposal\x12\x15.messages.MatchObject\x1a\x10.messages.Result\"\x00\x12?\n\rGetPlayerPool\x12\x14.messages.PlayerPool\x1a\x14.messages.PlayerPool\"\x00\x30\x01\x12=\n\x14GetAllIgnoredPlayers\x12\x11.messages.IlInput\x1a\x10.messages.Roster\"\x00\x12;\n\x12ListIgnoredPlayers\x12\x11.messages.IlInput\x1a\x10.messages.Roster\"\x00\x42\x37Z5github.com/GoogleCloudPlatform/open-match/internal/pbb\x06proto3')
|
||||
,
|
||||
dependencies=[api_dot_protobuf__spec_dot_messages__pb2.DESCRIPTOR,])
|
||||
|
||||
@ -50,7 +38,7 @@ _MMLOGIC = _descriptor.ServiceDescriptor(
|
||||
index=0,
|
||||
serialized_options=None,
|
||||
serialized_start=75,
|
||||
serialized_end=449,
|
||||
serialized_end=396,
|
||||
methods=[
|
||||
_descriptor.MethodDescriptor(
|
||||
name='GetProfile',
|
||||
@ -70,19 +58,10 @@ _MMLOGIC = _descriptor.ServiceDescriptor(
|
||||
output_type=api_dot_protobuf__spec_dot_messages__pb2._RESULT,
|
||||
serialized_options=None,
|
||||
),
|
||||
_descriptor.MethodDescriptor(
|
||||
name='ReturnError',
|
||||
full_name='api.MmLogic.ReturnError',
|
||||
index=2,
|
||||
containing_service=None,
|
||||
input_type=api_dot_protobuf__spec_dot_messages__pb2._RESULT,
|
||||
output_type=api_dot_protobuf__spec_dot_messages__pb2._RESULT,
|
||||
serialized_options=None,
|
||||
),
|
||||
_descriptor.MethodDescriptor(
|
||||
name='GetPlayerPool',
|
||||
full_name='api.MmLogic.GetPlayerPool',
|
||||
index=3,
|
||||
index=2,
|
||||
containing_service=None,
|
||||
input_type=api_dot_protobuf__spec_dot_messages__pb2._PLAYERPOOL,
|
||||
output_type=api_dot_protobuf__spec_dot_messages__pb2._PLAYERPOOL,
|
||||
@ -91,7 +70,7 @@ _MMLOGIC = _descriptor.ServiceDescriptor(
|
||||
_descriptor.MethodDescriptor(
|
||||
name='GetAllIgnoredPlayers',
|
||||
full_name='api.MmLogic.GetAllIgnoredPlayers',
|
||||
index=4,
|
||||
index=3,
|
||||
containing_service=None,
|
||||
input_type=api_dot_protobuf__spec_dot_messages__pb2._ILINPUT,
|
||||
output_type=api_dot_protobuf__spec_dot_messages__pb2._ROSTER,
|
||||
@ -100,7 +79,7 @@ _MMLOGIC = _descriptor.ServiceDescriptor(
|
||||
_descriptor.MethodDescriptor(
|
||||
name='ListIgnoredPlayers',
|
||||
full_name='api.MmLogic.ListIgnoredPlayers',
|
||||
index=5,
|
||||
index=4,
|
||||
containing_service=None,
|
||||
input_type=api_dot_protobuf__spec_dot_messages__pb2._ILINPUT,
|
||||
output_type=api_dot_protobuf__spec_dot_messages__pb2._ROSTER,
|
||||
|
@ -1,25 +1,14 @@
|
||||
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
|
||||
#Copyright 2018 Google LLC
|
||||
#Licensed under the Apache License, Version 2.0 (the "License");
|
||||
#you may not use this file except in compliance with the License.
|
||||
#You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
#Unless required by applicable law or agreed to in writing, software
|
||||
#distributed under the License is distributed on an "AS IS" BASIS,
|
||||
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
#See the License for the specific language governing permissions and
|
||||
#limitations under the License.
|
||||
import grpc
|
||||
|
||||
from api.protobuf_spec import messages_pb2 as api_dot_protobuf__spec_dot_messages__pb2
|
||||
|
||||
|
||||
class MmLogicStub(object):
|
||||
"""Profile and match object functions
|
||||
If your matchmaking logic makes a match, it should CreateProposal. If it
|
||||
cannot, it should ReturnError.
|
||||
"""The MMLogic API provides utility functions for common MMF functionality, such
|
||||
as retreiving profiles and players from state storage, writing results to state storage,
|
||||
and exposing metrics and statistics.
|
||||
Profile and match object functions
|
||||
"""
|
||||
|
||||
def __init__(self, channel):
|
||||
@ -38,11 +27,6 @@ class MmLogicStub(object):
|
||||
request_serializer=api_dot_protobuf__spec_dot_messages__pb2.MatchObject.SerializeToString,
|
||||
response_deserializer=api_dot_protobuf__spec_dot_messages__pb2.Result.FromString,
|
||||
)
|
||||
self.ReturnError = channel.unary_unary(
|
||||
'/api.MmLogic/ReturnError',
|
||||
request_serializer=api_dot_protobuf__spec_dot_messages__pb2.Result.SerializeToString,
|
||||
response_deserializer=api_dot_protobuf__spec_dot_messages__pb2.Result.FromString,
|
||||
)
|
||||
self.GetPlayerPool = channel.unary_stream(
|
||||
'/api.MmLogic/GetPlayerPool',
|
||||
request_serializer=api_dot_protobuf__spec_dot_messages__pb2.PlayerPool.SerializeToString,
|
||||
@ -61,9 +45,10 @@ class MmLogicStub(object):
|
||||
|
||||
|
||||
class MmLogicServicer(object):
|
||||
"""Profile and match object functions
|
||||
If your matchmaking logic makes a match, it should CreateProposal. If it
|
||||
cannot, it should ReturnError.
|
||||
"""The MMLogic API provides utility functions for common MMF functionality, such
|
||||
as retreiving profiles and players from state storage, writing results to state storage,
|
||||
and exposing metrics and statistics.
|
||||
Profile and match object functions
|
||||
"""
|
||||
|
||||
def GetProfile(self, request, context):
|
||||
@ -77,27 +62,49 @@ class MmLogicServicer(object):
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def CreateProposal(self, request, context):
|
||||
"""CreateProposal does the following:
|
||||
- adds all players in the Roster to the proposed player ignore list
|
||||
"""CreateProposal is called by MMFs that wish to write their results to
|
||||
a proposed MatchObject, that can be sent out the Backend API once it has
|
||||
been approved (by default, by the evaluator process).
|
||||
- adds all players in all Rosters to the proposed player ignore list
|
||||
- writes the proposed match to the provided key
|
||||
- adds that key to the list of proposals to be considered
|
||||
INPUT:
|
||||
* TO RETURN A MATCHOBJECT AFTER A SUCCESSFUL MMF RUN
|
||||
To create a match MatchObject message with these fields populated:
|
||||
- id, set to the value of the MMF_PROPOSAL_ID env var
|
||||
- properties
|
||||
- error. You must explicitly set this to an empty string if your MMF
|
||||
- roster, with the playerIDs filled in the 'players' repeated field.
|
||||
- [optional] pools, set to the output from the 'GetPlayerPools' call,
|
||||
will populate the pools with stats about how many players the filters
|
||||
matched and how long the filters took to run, which will be sent out
|
||||
the backend api along with your match results.
|
||||
was successful.
|
||||
* TO RETURN AN ERROR
|
||||
To report a failure or error, send a MatchObject message with these
|
||||
these fields populated:
|
||||
- id, set to the value of the MMF_ERROR_ID env var.
|
||||
- error, set to a string value describing the error your MMF encountered.
|
||||
- [optional] properties, anything you put here is returned to the
|
||||
backend along with your error.
|
||||
- [optional] rosters, anything you put here is returned to the
|
||||
backend along with your error.
|
||||
- [optional] pools, set to the output from the 'GetPlayerPools' call,
|
||||
will populate the pools with stats about how many players the filters
|
||||
matched and how long the filters took to run, which will be sent out
|
||||
the backend api along with your match results.
|
||||
OUTPUT: a Result message with a boolean success value and an error string
|
||||
if an error was encountered
|
||||
"""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def ReturnError(self, request, context):
|
||||
# missing associated documentation comment in .proto file
|
||||
pass
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def GetPlayerPool(self, request, context):
|
||||
"""Player listing and filtering functions
|
||||
|
||||
RetrievePlayerPool gets the list of players for every Filter in the
|
||||
PlayerPool, and then removes all players it finds in the ignore list. It
|
||||
RetrievePlayerPool gets the list of players that match every Filter in the
|
||||
PlayerPool, .excluding players in any configured ignore lists. It
|
||||
combines the results, and returns the resulting player pool.
|
||||
"""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
@ -114,8 +121,8 @@ class MmLogicServicer(object):
|
||||
raise NotImplementedError('Method not implemented!')
|
||||
|
||||
def ListIgnoredPlayers(self, request, context):
|
||||
"""RetrieveIgnoreList retrieves players from the ignore list specified in the
|
||||
config file under 'ignoreLists.proposedPlayers.key'.
|
||||
"""ListIgnoredPlayers retrieves players from the ignore list specified in the
|
||||
config file under 'ignoreLists.proposed.name'.
|
||||
"""
|
||||
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
||||
context.set_details('Method not implemented!')
|
||||
@ -134,11 +141,6 @@ def add_MmLogicServicer_to_server(servicer, server):
|
||||
request_deserializer=api_dot_protobuf__spec_dot_messages__pb2.MatchObject.FromString,
|
||||
response_serializer=api_dot_protobuf__spec_dot_messages__pb2.Result.SerializeToString,
|
||||
),
|
||||
'ReturnError': grpc.unary_unary_rpc_method_handler(
|
||||
servicer.ReturnError,
|
||||
request_deserializer=api_dot_protobuf__spec_dot_messages__pb2.Result.FromString,
|
||||
response_serializer=api_dot_protobuf__spec_dot_messages__pb2.Result.SerializeToString,
|
||||
),
|
||||
'GetPlayerPool': grpc.unary_stream_rpc_method_handler(
|
||||
servicer.GetPlayerPool,
|
||||
request_deserializer=api_dot_protobuf__spec_dot_messages__pb2.PlayerPool.FromString,
|
||||
|
@ -26,14 +26,9 @@ import pprint as pp
|
||||
|
||||
from timeit import default_timer as timer
|
||||
|
||||
# Load config file
|
||||
cfg = ''
|
||||
with open("matchmaker_config.json") as f:
|
||||
cfg = json.loads(f.read())
|
||||
|
||||
# Step 2 - Talk to Redis. This example uses the MM Logic API in OM to read/write to/from redis.
|
||||
# Establish grpc channel and make the API client stub
|
||||
api_conn_info = "%s:%d" % (cfg['api']['mmlogic']['hostname'], cfg['api']['mmlogic']['port'])
|
||||
api_conn_info = "%s:%d" % (os.environ["OM_MMLOGICAPI_SERVICE_HOST"],os.environ["OM_MMLOGICAPI_SERVICE_PORT"])
|
||||
with grpc.insecure_channel(api_conn_info) as channel:
|
||||
mmlogic_api = mmlogic_pb2_grpc.MmLogicStub(channel)
|
||||
|
||||
@ -54,7 +49,7 @@ with grpc.insecure_channel(api_conn_info) as channel:
|
||||
print("Retrieving pool '%s'" % empty_pool.name, end='')
|
||||
|
||||
# DEBUG: Print how long the filtering takes
|
||||
if cfg['debug']:
|
||||
if os.environ["DEBUG"]:
|
||||
start = timer()
|
||||
|
||||
# Pool filter results are streamed in chunks as they can be too large to send
|
||||
@ -71,9 +66,13 @@ with grpc.insecure_channel(api_conn_info) as channel:
|
||||
player_pools[empty_pool.name][player.id][attr.name] = attr.value
|
||||
except Exception as err:
|
||||
print("Error encountered: %s" % err)
|
||||
if cfg['debug']:
|
||||
if os.environ["DEBUG"]:
|
||||
print("\n'%s': count %06d | elapsed %0.3f" % (empty_pool.name, len(player_pools[empty_pool.name]),timer() - start))
|
||||
|
||||
num_players_total = 0
|
||||
for _, pool in player_pools.items():
|
||||
num_players_total += len(pool)
|
||||
|
||||
#################################################################
|
||||
# Step 5 - Run custom matchmaking logic to try to find a match
|
||||
# This is in the file mmf.py
|
||||
@ -81,7 +80,7 @@ with grpc.insecure_channel(api_conn_info) as channel:
|
||||
#################################################################
|
||||
|
||||
# DEBUG
|
||||
if cfg['debug']:
|
||||
if os.environ["DEBUG"]:
|
||||
print("======== match_properties")
|
||||
pp.pprint(results)
|
||||
|
||||
@ -95,7 +94,7 @@ with grpc.insecure_channel(api_conn_info) as channel:
|
||||
# Access the rosters in dict form within the properties json.
|
||||
# It is stored at the key specified in the config file.
|
||||
rosters_dict = results
|
||||
for partial_key in cfg['jsonkeys']['rosters'].split('.'):
|
||||
for partial_key in os.environ["JSONKEYS_ROSTERS"].split('.'):
|
||||
rosters_dict = rosters_dict.get(partial_key, {})
|
||||
|
||||
# Unmarshal the rosters into the MatchObject
|
||||
@ -103,13 +102,20 @@ with grpc.insecure_channel(api_conn_info) as channel:
|
||||
mo.rosters.extend([Parse(json.dumps(roster), mmlogic.Roster(), ignore_unknown_fields=True)])
|
||||
|
||||
#DEBUG: writing to error key prevents evalutor run
|
||||
if cfg['debug']:
|
||||
if os.environ["DEBUG"]:
|
||||
#mo.id = os.environ["MMF_ERROR_ID"]
|
||||
#mo.error = "skip evaluator"
|
||||
print("======== MMF results:")
|
||||
pp.pprint(mo)
|
||||
|
||||
# Step 6 - Write the outcome of the matchmaking logic back to state storage.
|
||||
# Return error when there are no players in the pools
|
||||
if num_players_total == 0:
|
||||
if cfg['debug']:
|
||||
print("All player pools are empty, writing to error to skip the evaluator")
|
||||
mo.id = os.environ["MMF_ERROR_ID"]
|
||||
mo.error = "insufficient players"
|
||||
|
||||
# Step 6 - Write the outcome of the matchmaking logic back to state storage.
|
||||
# Step 7 - Remove the selected players from consideration by other MMFs.
|
||||
# CreateProposal does both of these for you, and some other items as well.
|
||||
success = mmlogic_api.CreateProposal(mo)
|
||||
|
@ -1 +0,0 @@
|
||||
../../../../config/matchmaker_config.json
|
@ -31,9 +31,13 @@ def makeMatches(profile_dict, player_pools):
|
||||
for roster in profile_dict['properties']['rosters']:
|
||||
for player in roster['players']:
|
||||
if 'pool' in player:
|
||||
player['id'] = random.choice(list(player_pools[player['pool']]))
|
||||
del player_pools[player['pool']][player['id']]
|
||||
print("Selected player %s from pool %s (strategy: RANDOM)" % (player['id'], player['pool']))
|
||||
player_pool = list(player_pools[player['pool']])
|
||||
if len(player_pool) > 0:
|
||||
player['id'] = random.choice(player_pool)
|
||||
del player_pools[player['pool']][player['id']]
|
||||
print("Selected player %s from pool %s (strategy: RANDOM)" % (player['id'], player['pool']))
|
||||
else:
|
||||
print("Player pool %s is empty (roster %s)" % (player['pool'], roster['name']))
|
||||
else:
|
||||
print(player)
|
||||
return profile_dict
|
||||
|
39
go.mod
Normal file
39
go.mod
Normal file
@ -0,0 +1,39 @@
|
||||
module github.com/GoogleCloudPlatform/open-match
|
||||
|
||||
go 1.12
|
||||
|
||||
require (
|
||||
github.com/TV4/logrus-stackdriver-formatter v0.1.0
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible
|
||||
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b
|
||||
github.com/gogo/protobuf v1.2.1
|
||||
github.com/golang/protobuf v1.3.0
|
||||
github.com/gomodule/redigo v1.7.0
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c // indirect
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf // indirect
|
||||
github.com/googleapis/gnostic v0.2.0 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc // indirect
|
||||
github.com/json-iterator/go v1.1.6 // indirect
|
||||
github.com/kr/pretty v0.1.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1
|
||||
github.com/rs/xid v1.2.1
|
||||
github.com/sirupsen/logrus v1.4.0
|
||||
github.com/spf13/viper v1.3.2
|
||||
github.com/tidwall/gjson v1.2.1
|
||||
github.com/tidwall/match v1.0.1 // indirect
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51 // indirect
|
||||
github.com/tidwall/sjson v1.0.4
|
||||
go.opencensus.io v0.19.1
|
||||
golang.org/x/net v0.0.0-20190313082753-5c2c250b6a70
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect
|
||||
google.golang.org/grpc v1.19.0
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
k8s.io/api v0.0.0-20190222213804-5cb15d344471
|
||||
k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628
|
||||
k8s.io/client-go v10.0.0+incompatible
|
||||
k8s.io/klog v0.2.0 // indirect
|
||||
sigs.k8s.io/yaml v1.1.0 // indirect
|
||||
)
|
205
go.sum
Normal file
205
go.sum
Normal file
@ -0,0 +1,205 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
|
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/TV4/logrus-stackdriver-formatter v0.1.0 h1:nFea8RiX7ecTnWPM+9FIqwZYJdcGo58CHMGIVdYzMXg=
|
||||
github.com/TV4/logrus-stackdriver-formatter v0.1.0/go.mod h1:wwS7hOiBvP6SBD0UXCa767+VhHkaXrfX0MzUojYcN0Q=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible h1:tKJnvO2kl0zmb/jA5UKAt4VoEVw1qxKWjE/Bpp46npY=
|
||||
github.com/cenkalti/backoff v2.1.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
|
||||
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
|
||||
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA=
|
||||
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw=
|
||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
|
||||
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
|
||||
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/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk=
|
||||
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
|
||||
github.com/gomodule/redigo v1.7.0 h1:ZKld1VOtsGhAe37E7wMxEDgAlGM5dvFY+DiOhSkhP9Y=
|
||||
github.com/gomodule/redigo v1.7.0/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf h1:+RRA9JqSOZFfKrOeqr2z77+8R2RKyh8PG66dcu1V0ck=
|
||||
github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
|
||||
github.com/googleapis/gnostic v0.2.0 h1:l6N3VoaVzTncYYW+9yOz2LJJammFZGBO13sqgEhpy9g=
|
||||
github.com/googleapis/gnostic v0.2.0/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc h1:f8eY6cV/x1x+HLjOp4r72s/31/V2aTUtg5oKRRPf8/Q=
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.6.2/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw=
|
||||
github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCOH9wdo=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/json-iterator/go v1.1.6 h1:MrUvLMLTMxbqFJ9kzlvat/rYZqZnW3u4wkLzWTaFwKs=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
|
||||
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
|
||||
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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 h1:D+CiwcpGTW6pL6bv6KI3KbyEyCKyS+1JWS2h8PNDnGA=
|
||||
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f h1:BVwpUVJDADN2ufcGik7W992pyps0wZ888b/y9GXcLTU=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/common v0.2.0 h1:kUZDBDTdBVBYBj5Tmh2NZLlF60mfjA27rM34b+cVwNU=
|
||||
github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg=
|
||||
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
||||
github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1 h1:+kGqA4dNN5hn7WwvKdzHl0rdN5AEkbNZd0VjRltAiZg=
|
||||
github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1/go.mod h1:JaY6n2sDr+z2WTsXkOmNRUfDy6FN0L6Nk7x06ndm4tY=
|
||||
github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/sirupsen/logrus v1.4.0 h1:yKenngtzGh+cUSSh6GWbxW2abRqhYUSR/t/6+2QqNvE=
|
||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
||||
github.com/spf13/afero v1.1.2 h1:m8/z1t7/fwjysjQRYbP0RD+bUIF/8tJwPdEZsI83ACI=
|
||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
|
||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
|
||||
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/tidwall/gjson v1.2.1 h1:j0efZLrZUvNerEf6xqoi0NjWMK5YlLrR7Guo/dxY174=
|
||||
github.com/tidwall/gjson v1.2.1/go.mod h1:c/nTNbUr0E0OrXEhq1pwa8iEgc2DOt4ZZqAt1HtCkPA=
|
||||
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
|
||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51 h1:BP2bjP495BBPaBcS5rmqviTfrOkN5rO5ceKAMRZCRFc=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/sjson v1.0.4 h1:UcdIRXff12Lpnu3OLtZvnc03g4vH2suXDXhBwBqmzYg=
|
||||
github.com/tidwall/sjson v1.0.4/go.mod h1:bURseu1nuBkFpIES5cz6zBtjmYeOQmEESshn7VpF15Y=
|
||||
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
|
||||
go.opencensus.io v0.19.1 h1:gPYKQ/GAQYR2ksU+qXNmq3CrOZWT1kkryvW6O0v1acY=
|
||||
go.opencensus.io v0.19.1/go.mod h1:gug0GbSHa8Pafr0d2urOSgoXHZ6x/RUlaiT0d9pqb4A=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
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-20181106065722-10aee1819953/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-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190313082753-5c2c250b6a70 h1:0OwHPyvXNyZS9VW4XXoGkWOwhrMN52Y4n/gSxvJOgj0=
|
||||
golang.org/x/net v0.0.0-20190313082753-5c2c250b6a70/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
|
||||
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
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 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/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-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb h1:dQshZyyJ5W/Xk8myF4GKBak1pZW6EywJuQ8+44EQhGA=
|
||||
google.golang.org/genproto v0.0.0-20181219182458-5a97ab628bfb/go.mod h1:7Ep/1NZk928CDR8SjdVbjWNpdIf6nzjE3BTgJDr2Atg=
|
||||
google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20180920025451-e3ad64cb4ed3/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
k8s.io/api v0.0.0-20190222213804-5cb15d344471 h1:MzQGt8qWQCR+39kbYRd0uQqsvSidpYqJLFeWiJ9l4OE=
|
||||
k8s.io/api v0.0.0-20190222213804-5cb15d344471/go.mod h1:iuAfoD4hCxJ8Onx9kaTIt30j7jUFS00AXQi6QMi99vA=
|
||||
k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628 h1:UYfHH+KEF88OTg+GojQUwFTNxbxwmoktLwutUzR0GPg=
|
||||
k8s.io/apimachinery v0.0.0-20190221213512-86fb29eff628/go.mod h1:ccL7Eh7zubPUSh9A3USN90/OzHNSVN6zxzde07TDCL0=
|
||||
k8s.io/apimachinery v0.0.0-20190313115320-c9defaaddf6f h1:6ojhffWUv9DZ8i4L2LIvSjbWH3fXfP6PmrTNwXHHMhM=
|
||||
k8s.io/client-go v10.0.0+incompatible h1:F1IqCqw7oMBzDkqlcBymRq1450wD0eNqLE9jzUrIi34=
|
||||
k8s.io/client-go v10.0.0+incompatible/go.mod h1:7vJpHMYJwNQCWgzmNV+VYUl1zCObLyodBc8nIyt8L5s=
|
||||
k8s.io/klog v0.2.0 h1:0ElL0OHzF3N+OhoJTL0uca20SxtYt4X4+bzHeqrB83c=
|
||||
k8s.io/klog v0.2.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
|
||||
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
24
install/helm/README.md
Normal file
24
install/helm/README.md
Normal file
@ -0,0 +1,24 @@
|
||||
Open Match Helm Chart
|
||||
=====================
|
||||
|
||||
Open Match provides a Helm chart to quickly
|
||||
|
||||
```bash
|
||||
# Install Helm and Tiller
|
||||
# See https://github.com/helm/helm/releases for
|
||||
cd /tmp && curl -Lo helm.tar.gz https://storage.googleapis.com/kubernetes-helm/helm-v2.13.0-linux-amd64.tar.gz && tar xvzf helm.tar.gz --strip-components 1 && mv helm $(PREFIX)/bin/helm && mv tiller $(PREFIX)/bin/tiller
|
||||
|
||||
# Install Helm to Kubernetes Cluster
|
||||
kubectl create serviceaccount --namespace kube-system tiller
|
||||
helm init --service-account tiller --force-upgrade
|
||||
kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
|
||||
# Run if RBAC is enabled.
|
||||
kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
|
||||
|
||||
# Deploy Open Match
|
||||
helm upgrade --install --wait --debug open-match \
|
||||
install/helm/open-match \
|
||||
--namespace=open-match \
|
||||
--set openmatch.image.registry=$(REGISTRY) \
|
||||
--set openmatch.image.tag=$(TAG)
|
||||
```
|
36
install/helm/open-match-example/Chart.yaml
Normal file
36
install/helm/open-match-example/Chart.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
# Copyright 2019 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
apiVersion: v1
|
||||
appVersion: "0.4.0"
|
||||
version: 0.4.0
|
||||
name: open-match-example
|
||||
description: Flexible, extensible, and scalable video game matchmaking.
|
||||
keywords:
|
||||
- kubernetes
|
||||
- game-development
|
||||
- multiplayer
|
||||
- matchmaking
|
||||
- go
|
||||
- golang
|
||||
home: https://github.com/GoogleCloudPlatform/open-match
|
||||
sources:
|
||||
- https://github.com/GoogleCloudPlatform/open-match
|
||||
maintainers:
|
||||
- name: open-match
|
||||
email: open-match-discuss@googlegroups.com
|
||||
url: https://groups.google.com/forum/#!forum/open-match-discuss
|
||||
engine: gotpl
|
||||
#icon: https://github.com/GoogleCloudPlatform/open-match/raw/master/docs/open-match.png
|
||||
tillerVersion: ">2.10.0"
|
14
install/helm/open-match-example/README.md
Normal file
14
install/helm/open-match-example/README.md
Normal file
@ -0,0 +1,14 @@
|
||||
Open Match Example Helm Chart
|
||||
=============================
|
||||
|
||||
This chart installs the Open Match example clientloadgen, frontendclient, backendclient, and example MMF and evaluator.
|
||||
|
||||
To deploy this chart run:
|
||||
|
||||
```bash
|
||||
helm upgrade --install --wait --debug open-match-example
|
||||
install/helm/open-match-example \
|
||||
--namespace=open-match \
|
||||
--set openmatch.image.registry=$(REGISTRY) \
|
||||
--set openmatch.image.tag=$(TAG)
|
||||
```
|
3
install/helm/open-match-example/templates/NOTES.txt
Normal file
3
install/helm/open-match-example/templates/NOTES.txt
Normal file
@ -0,0 +1,3 @@
|
||||
The Open Match examples have been installed in the namespace {{ .Release.Namespace }}.
|
||||
|
||||
You can watch the status by running 'kubectl --namespace {{ .Release.Namespace }} get pods,svc'
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user