Skip to content

Commit

Permalink
C++ SDK implementation, example and doc
Browse files Browse the repository at this point in the history
This includes a very basic "server" that
integrates with the SDK to show how it works
as well as expansion of the SDK docs to explain
how they work.

This also includes working the SDK code gen
and compilation (on linux at least) into the
main build process as well.

Closes #7
  • Loading branch information
markmandel committed Dec 22, 2017
1 parent dd27d28 commit cb8dc9f
Show file tree
Hide file tree
Showing 21 changed files with 1,462 additions and 60 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@
!.gitignore
*.iml
bin
*.o
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@
Agon is a library for running dedicated game servers on [Kubernetes](https://kubernetes.io).

## Disclaimer
This software is currenty alpha, and subject to change. Not to be used in production systems.
This software is currently alpha, and subject to change. Not to be used in production systems.

## Roadmap for 0.1 release
- Develop a [Custom Resource Defintion](https://kubernetes.io/docs/concepts/api-extension/custom-resources/#customresourcedefinitions) for dedicated game server
- Sidecar for managing the DGS lifecycle and recorded status, e.g. registering the port the server has started on
- A Kubernetes operator that registers the CRD, and creates a Pod with the DGS in it, with the accompanying sidecar for system registration.
- A basic client library for integration with a DGS
- Simple example code
- Documentation of the above
## Major Features
- Be able to define a `GameServer` within Kubernetes - either through yaml or the via API
- Manage GameServer lifecycles - including health checking and connection information.
- Client SDKs for integration with dedicated game servers to work with Agon.

## Requirements
- Requires a Kubernetes cluster of version 1.8+
- Open the firewall access for the range of ports that Game Servers can be connected to in the cluster.
- Game Servers must have the [project SDK](sdks) integrated, to manage Game Server state, health checking, etc.

## Installation
`kubectl apply -f install.yaml`
Expand All @@ -27,9 +25,11 @@ _Note:_ There has yet to be a release of Agon, so you will need to edit the `ins
development release or [build from source](build/README.md)

## Usage
See the [examples](./examples) directory
See the [sdks](sdks) and [examples](examples) directories.

More documentation forthcoming.

## Development
## Development and Contribution
See the tools in the [build](build/README.md) directory for testing and building Agon from source.

## Licence
Expand Down
31 changes: 20 additions & 11 deletions build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,13 @@ go_version_flags = -ldflags "-X github.com/agonio/agon/pkg.Version=$(VERSION)"
# |___/

# build all
build: build-gameservers-controller-image build-gameservers-sidecar-image
build: build-images build-sdks

# build the docker images
build-images: build-gameservers-controller-image build-gameservers-sidecar-image

#build all the sdks
build-sdks: build-sdk-cpp

# Run all tests
test: ensure-image
Expand Down Expand Up @@ -105,13 +111,18 @@ build-gameservers-sidecar-binary: ensure-image
build-gameservers-sidecar-image: ensure-image build-gameservers-sidecar-binary
docker build $(agon_path)/gameservers/sidecar/ --tag=$(sidecar_tag)

# Build the cpp sdk linux archive
build-sdk-cpp: ensure-image
docker run --rm $(common_mounts) -w $(mount_path)/sdks/cpp --entrypoint make $(build_tag) build install archive VERSION=$(VERSION)

# push the gameservers sidecar image
push-gameservers-sidecar-image: ensure-image
docker push $(sidecar_tag)

# Generate the sidecar gRPC code
gen-gameservers-sidecar-grpc: ensure-image
# Generate the SDK gRPC server and client code
gen-gameservers-sdk-grpc: ensure-image
docker run --rm $(common_mounts) --entrypoint="/root/gen-grpc-go.sh" $(build_tag)
docker run --rm $(common_mounts) --entrypoint="/root/gen-grpc-cpp.sh" $(build_tag)

# Generate the client for our CustomResourceDefinition
gen-crd-client: ensure-image
Expand All @@ -137,14 +148,12 @@ godoc:
docker run -p 8888:8888 --rm $(common_mounts) -v $(build_path)/.index:/root/.index \
--entrypoint=godoc $(build_tag) -http=":8888" -index=true -index_files=/root/.index

.PHONY: build-image

# Creates the build docker image
build-image:
build-build-image:
docker build --tag=$(build_tag) $(build_path)/build-image

# Deletes the local build docker image
clean-image:
clean-build-image:
docker rmi $(build_tag)

ensure-config:
Expand All @@ -154,7 +163,7 @@ ensure-config:
ensure-image: ensure-config
@if [ -z $$(docker images -q $(build_tag)) ]; then\
echo "Could not find $(build_tag) image. Building...";\
$(MAKE) build-image;\
$(MAKE) build-build-image;\
fi

# Initialise the gcloud login and project configuration, if you are working with GCP
Expand All @@ -164,23 +173,23 @@ gcloud-init: ensure-config
--entrypoint="gcloud" $(build_tag) init

# Creates and authenticates a small, 3 node GKE cluster to work against
gcloud-test-cluster:
gcloud-test-cluster: ensure-image
docker run --rm -it $(common_mounts) \
--entrypoint="gcloud" $(build_tag) \
deployment-manager deployments create test-cluster --config=$(mount_path)/build/gke-test-cluster/deployment.yml
$(MAKE) gcloud-auth-cluster

# Pulls down authentication information for kubectl against a cluster, name can be specified through CLUSTER_NAME
# (defaults to 'test-cluster')
gcloud-auth-cluster:
gcloud-auth-cluster: ensure-image
docker run --rm $(common_mounts) --entrypoint="gcloud" $(build_tag) config set container/cluster $(CLUSTER_NAME)
docker run --rm $(common_mounts) --entrypoint="gcloud" $(build_tag) config set compute/zone \
`grep zone: $(build_path)/gke-test-cluster/deployment.yml | sed 's/zone: //'`
docker run --rm $(common_mounts) --entrypoint="gcloud" $(build_tag) container clusters get-credentials $(CLUSTER_NAME)

# authenticate our docker configuration so that you can do a docker push directly
# to the gcr.io repository
gcloud-auth-docker:
gcloud-auth-docker: ensure-image
-sudo rm -rf /tmp/gcloud-auth-docker
mkdir -p /tmp/gcloud-auth-docker
-cp ~/.dockercfg /tmp/gcloud-auth-docker
Expand Down
66 changes: 49 additions & 17 deletions build/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Build
# Developing, Testing and Building Agon

Tooling for building and developing against Agon, with only dependencies being
[Make](https://www.gnu.org/software/make/) and [Docker](https://www.docker.com)
Expand All @@ -7,25 +7,48 @@ Rather than installing all the dependencies locally, you can test and build Agon
built from the Dockerfile in this directory. There is an accompanying Makefile for all the common
tasks you may wish to accomplish.

<!-- ToC start -->
## Table of Contents

1. [GOPATH](#gopath)
1. [Testing and Building](#testing-and-building)
1. [Running a Test Google Kubernetes Engine Cluster](#running-a-test-google-kubernetes-engine-cluster)
1. [Running a Test Minikube cluster](#running-a-test-minikube-cluster)
1. [Next Steps](#next-steps)
1. [Make Variable Reference](#make-variable-reference)
1. [VERSION](#version)
1. [REGISTRY](#registry)
1. [KUBECONFIG](#kubeconfig)
1. [CLUSTER_NAME](#cluster_name)
1. [Make Target Reference](#make-target-reference)
1. [Development Targets](#development-targets)
1. [Build Image Targets](#build-image-targets)
1. [Google Cloud Platform](#google-cloud-platform)
<!-- ToC end -->

## GOPATH

This project should be cloned to the directory `$GOPATH/src/github.com/agonio/agon`
for when you are developing locally, and require package resolution in your IDE.

This is not required if you are simply building using the `make` targets

### Testing and Building
## Testing and Building
Make sure you are in the `build` directory to start.

First, let's test all the code. To do this, run `make test`, which will execute all the unit tests for the codebase.

If you haven't run any of the `build` make targets before then this will also create the build image, and then run the tests.
Building the `build-image` may take a few minutes to download all the dependencies, so feel
free to make cup of tea or coffee at this point. ☕️

The build image is only created the first time one of the make targets is executed, and will only rebuild if the build
Dockerfile has changed.

Assuming that the tests all pass, let's go ahead an compile the code and build the Docker images that Agon consists of.

To compile the code and create the Docker images run `make build`. This will compile the code and create the docker image.
To compile the code, create the Docker images, and compile and archive the sdks,
run `make build`. This will compile the code and create the docker image.
You may note that the docker image is tagged with a concatenation of the upcoming release number and short git hash
for the current commit. This has also been set in the code itself, so that it can be seen in log statements.

Expand Down Expand Up @@ -108,18 +131,27 @@ All targets will create the build image if it is not present.
Targets for developing with the build image

#### `make build`
Build all the images required for Agon, as well as the SDKs

#### `make build-images`
Build all the images required for Agon

#### `make build-sdks`
Build all the sdks required for Agon

#### `make build-sdk-cpp`
Build the cpp sdk static and dynamic libraries (linux libraries only)

#### `make test`
Run all tests

### `make push`
#### `make push`
Pushes all built images up to the `$(REGISTRY)`

### `make shell`
#### `make shell`
Run a bash shell with the developer tools (go tooling, kubectl, etc) and source code in it.

### `make godoc`
#### `make godoc`
Run a container with godoc (search index enabled)

#### `make build-gameservers-controller-image`
Expand All @@ -131,37 +163,37 @@ Compile the gameserver sidecar and then build the docker image
#### `make gen-crd-client`
Generate the Custom Resource Definition client(s)

#### `make gen-gameservers-sidecar-grpc`
Generate the gRPC sidecar Server and Client
#### `make gen-gameservers-sdk-grpc`
Generate the SDK gRPC server and client code

### Build Image Targets

Targets for building the build image

### `make clean-config`
#### `make clean-config`
Cleans the kubernetes and gcloud configurations

### `make clean-image`
#### `make clean-build-image`
Deletes the local build docker image

### `make build-image`
#### `make build-build-image`
Creates the build docker image

## Google Cloud Platform
### Google Cloud Platform

A set of utilities for setting up a Container Engine cluster on Google Cloud Platform,
since it's an easy way to get a test cluster working with Kubernetes.

### `make gcloud-init`
#### `make gcloud-init`
Initialise the gcloud login and project configuration, if you are working with GCP

### `make gcloud-test-cluster`
#### `make gcloud-test-cluster`
Creates and authenticates a small, 3 node GKE cluster to work against

### `make gcloud-auth-cluster`
#### `make gcloud-auth-cluster`
Pulls down authentication information for kubectl against a cluster, name can be specified through CLUSTER_NAME
(defaults to 'test-cluster')

### `make gcloud-auth-docker`
#### `make gcloud-auth-docker`
Creates a short lived access to Google Cloud container repositories, so that you are able to call
`docker push` directly. Useful when used in combination with `make push` command.
`docker push` directly. Useful when used in combination with `make push` command.
45 changes: 23 additions & 22 deletions build/build-image/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,42 @@
# See the License for the specific language governing permissions and
# limitations under the License.

FROM golang:1.9.2
# compiling proto + grpc takes an exceptionally long time
# so we'll use that as the base.
FROM grpc/cxx:1.8

RUN apt-get update && apt-get install -y wget unzip bash-completion rsync
RUN apt-get update && \
apt-get install -y wget rsync make python bash-completion && \
apt-get clean

WORKDIR /
# install go
WORKDIR /usr/local
ENV GO_VERSION=1.9.2
ENV GOPATH /go
RUN wget -q https://redirector.gvt1.com/edgedl/go/go${GO_VERSION}.linux-amd64.tar.gz && \
tar -xzf go${GO_VERSION}.linux-amd64.tar.gz && rm go${GO_VERSION}.linux-amd64.tar.gz && mkdir ${GOPATH}

# install gcloud + kubectl, because it's an easy way to test/dev against kubernetes.
RUN wget -q https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.zip && unzip -q google-cloud-sdk.zip && rm google-cloud-sdk.zip
RUN /google-cloud-sdk/install.sh --usage-reporting=true --path-update=true --bash-completion=true --rc-path=/root/.bashrc
ENV PATH /google-cloud-sdk/bin:$PATH
WORKDIR /opt
RUN wget -q https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.zip && unzip -q google-cloud-sdk.zip && \
rm google-cloud-sdk.zip && \
/opt/google-cloud-sdk/install.sh --usage-reporting=true --path-update=true --bash-completion=true --rc-path=/root/.bashrc

# update the path for both go and gcloud
ENV PATH /usr/local/go/bin:/opt/google-cloud-sdk/bin:$PATH

# RUN gcloud components update
RUN gcloud components update && gcloud components install kubectl
RUN echo "source <(kubectl completion bash)" >> /root/.bashrc

# install protoc for grpc
ENV PB_VER 3.5.0
ENV PB_URL https://github.com/google/protobuf/releases/download/v${PB_VER}/protoc-${PB_VER}-linux-x86_64.zip
RUN mkdir -p /tmp/protoc && \
curl -L ${PB_URL} > /tmp/protoc/protoc.zip && \
cd /tmp/protoc && \
unzip protoc.zip && \
cp /tmp/protoc/bin/protoc /usr/local/bin && \
cp -R /tmp/protoc/include/* /usr/local/include && \
chmod go+rx /usr/local/bin/protoc && \
cd /tmp && \
rm -r /tmp/protoc

# install go tooling for building and testing
# install go tooling for development, building and testing
RUN go get -u github.com/golang/dep/cmd/dep && \
go get -u github.com/alecthomas/gometalinter && \
go get -u github.com/golang/protobuf/protoc-gen-go && \
/go/bin/gometalinter --install

# install the release branch of the code generator tools
RUN cd /go/src && mkdir -p k8s.io && cd k8s.io && \
RUN mkdir -p /go/src && cd /go/src && mkdir -p k8s.io && cd k8s.io && \
git clone -b release-1.8 --depth=3 https://github.com/kubernetes/code-generator.git

# make sure we keep the path to go
Expand All @@ -56,4 +57,4 @@ RUN echo "export PATH=/usr/local/go/bin:/go/bin/:\$PATH" >> /root/.bashrc
COPY *.sh /root/
RUN chmod +x /root/*.sh

ENTRYPOINT kubectl
WORKDIR /go
25 changes: 25 additions & 0 deletions build/build-image/gen-grpc-cpp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/bin/env bash

# Copyright 2017 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.

cd /go/src/github.com/agonio/agon
protoc -I . --grpc_out=./sdks/cpp --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` sdk.proto
protoc -I . --cpp_out=./sdks/cpp sdk.proto
mkdir /tmp/cpp
ls ./sdks/cpp | xargs -I@ bash -c "cat ./build/boilerplate.go.txt ./sdks/cpp/@ >> /tmp/cpp/@"
# already has a header, so we'll remove it
rm /tmp/cpp/sdk.grpc.pb.h
mv /tmp/cpp/* ./sdks/cpp/

23 changes: 23 additions & 0 deletions examples/cpp-simple/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2017 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.

FROM debian:stretch
RUN useradd -m server

COPY ./bin/server-static /home/server/server-static
RUN chown -R server /home/server && \
chmod o+x /home/server/server-static

USER server
ENTRYPOINT /home/server/server-static
Loading

0 comments on commit cb8dc9f

Please sign in to comment.