Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zinstall.yaml to install Agon. #22

Merged
merged 1 commit into from Dec 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions README.md
Expand Up @@ -13,6 +13,19 @@ This software is currenty alpha, and subject to change. Not to be used in produc
- Simple example code
- Documentation of the above

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

## Installation
`kubectl apply -f install.yaml`

If you are running your own Docker repository, make a local copy of install.yaml
and edit to match your settings.

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

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

Expand Down
46 changes: 32 additions & 14 deletions build/README.md
@@ -1,34 +1,52 @@
# Build

Tooling for building and developing against Agon, with only dependency being [Docker](https://www.docker.com).
Tooling for building and developing against Agon, with only dependencies being
[Make](https://www.gnu.org/software/make/) and [Docker](https://www.docker.com)

Rather than installing all the dependencies locally, you can test and build Agon using the Docker image that can
be build from the Dockerfile based image in this directory. There is an accompanying Makefile for all the common
Rather than installing all the dependencies locally, you can test and build Agon using the Docker image that is
built from the Dockerfile in this directory. There is an accompanying Makefile for all the common
tasks you may wish to accomplish.

## 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

## Make Targets

## Development Targets
All targets will create the build image if it is not present.

### Development Targets

Targets for developing with the build image

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

#### `make test`
Run all tests

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

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

#### `make build-gameservers-controller-image`
Compile the gameserver controller and then build the docker image

### `make build-gameservers-sidecar-image`
#### `make build-gameservers-sidecar-image`
Compile the gameserver sidecar and then build the docker image

### `make test`
Run all tests

### `make gen-client`
#### `make gen-crd-client`
Generate the Custom Resource Definition client(s)

### `make shell`
Run a bash shell with the developer tools ad source code in it.
Also creates the image if it doesn't exist
#### `make gen-gameservers-sidecar-grpc`
Generate the gRPC sidecar Server and Client

## Build Image Targets
### Build Image Targets

Targets for building the build image

Expand Down
27 changes: 3 additions & 24 deletions gameservers/controller/controller.go
Expand Up @@ -110,11 +110,7 @@ func NewController(sidecarImage string,
func (c Controller) Run(threadiness int, stop <-chan struct{}) error {
defer c.queue.ShutDown()

err := c.createCRDIfDoesntExist()
if err != nil {
return err
}
err = c.waitForEstablishedCRD()
err := c.waitForEstablishedCRD()
if err != nil {
return err
}
Expand Down Expand Up @@ -400,28 +396,11 @@ func (c Controller) externalIP(pod *corev1.Pod) (string, error) {
return "", errors.Errorf("Could not find an external ip for Node: #%s", node.ObjectMeta.Name)
}

// createCRDIfDoesntExist creates the GameServer CRD if it doesn't exist.
// only returns an error if something goes wrong
func (c Controller) createCRDIfDoesntExist() error {
crd, err := c.crdGetter.Create(stablev1alpha1.GameServerCRD())
if err != nil {
if !k8serrors.IsAlreadyExists(err) {
return errors.Wrap(err, "error creating gameserver custom resource definition")
}
logrus.Info("gameserver custom resource definition already exists.")
} else {
logrus.WithField("crd", crd).Info("gameserver custom resource definition created successfully")
}

return nil
}

// waitForEstablishedCRD blocks until CRD comes to an Established state.
// Has a deadline of 60 seconds for this to occur.
func (c Controller) waitForEstablishedCRD() error {
crdName := stablev1alpha1.GameServerCRD().ObjectMeta.Name
return wait.PollImmediate(500*time.Millisecond, 60*time.Second, func() (done bool, err error) {
crd, err := c.crdGetter.Get(crdName, metav1.GetOptions{})
crd, err := c.crdGetter.Get("gameservers.stable.agon.io", metav1.GetOptions{})
if err != nil {
return false, err
}
Expand All @@ -430,7 +409,7 @@ func (c Controller) waitForEstablishedCRD() error {
switch cond.Type {
case apiv1beta1.Established:
if cond.Status == apiv1beta1.ConditionTrue {
logrus.WithField("crd", crd).Info("gameserver custom resource definition is established")
logrus.WithField("crd", crd).Info("GameServer custom resource definition is established")
return true, err
}
}
Expand Down
54 changes: 8 additions & 46 deletions gameservers/controller/controller_test.go
Expand Up @@ -15,7 +15,6 @@
package main

import (
"errors"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -43,44 +42,6 @@ import (
"k8s.io/client-go/tools/cache"
)

func TestControllerCreateCRDIfDoesntExist(t *testing.T) {
t.Parallel()

t.Run("CRD doesn't exist", func(t *testing.T) {
con, mocks := newFakeController()
var crd *v1beta1.CustomResourceDefinition
mocks.extClient.AddReactor("create", "customresourcedefinitions", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
a := action.(k8stesting.CreateAction)
crd = a.GetObject().(*v1beta1.CustomResourceDefinition)
return true, nil, nil
})

err := con.createCRDIfDoesntExist()
assert.Nil(t, err, "CRD Should be created: %v", err)
assert.Equal(t, v1alpha1.GameServerCRD(), crd)
})

t.Run("CRD does exist", func(t *testing.T) {
con, mocks := newFakeController()
mocks.extClient.AddReactor("create", "customresourcedefinitions", func(action k8stesting.Action) (handled bool, ret runtime.Object, err error) {
err = k8serrors.NewAlreadyExists(schema.GroupResource{Group: stable.GroupName, Resource: "gameserver"}, "Foo")
return true, nil, err
})
err := con.createCRDIfDoesntExist()
assert.Nil(t, err, "CRD Should not be created, but not throw an error: %v", err)
})

t.Run("Something bad happens", func(t *testing.T) {
con, mocks := newFakeController()
fixture := errors.New("this is a custom error")
mocks.extClient.AddReactor("create", "customresourcedefinitions", func(action k8stesting.Action) (bool, runtime.Object, error) {
return true, nil, fixture
})
err := con.createCRDIfDoesntExist()
assert.NotNil(t, err, "Custom error should be returned")
})
}

func TestControllerWaitForEstablishedCRD(t *testing.T) {
t.Parallel()
crd := newEstablishedCRD()
Expand Down Expand Up @@ -608,13 +569,14 @@ func newSingeContainerSpec() v1alpha1.GameServerSpec {
}

func newEstablishedCRD() *v1beta1.CustomResourceDefinition {
crd := v1alpha1.GameServerCRD()
crd.Status.Conditions = []v1beta1.CustomResourceDefinitionCondition{{
Type: v1beta1.Established,
Status: v1beta1.ConditionTrue,
}}

return crd
return &v1beta1.CustomResourceDefinition{
Status: v1beta1.CustomResourceDefinitionStatus{
Conditions: []v1beta1.CustomResourceDefinitionCondition{{
Type: v1beta1.Established,
Status: v1beta1.ConditionTrue,
}},
},
}
}

func startInformers(c *Controller, mocks mocks) chan struct{} {
Expand Down
21 changes: 19 additions & 2 deletions gameservers/controller/deployment.yaml → install.yaml
Expand Up @@ -12,6 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: gameservers.stable.agon.io
spec:
group: stable.agon.io
version: v1alpha1
scope: Namespaced
names:
kind: GameServer
plural: gameservers
shortNames:
- gs
singular: gameserver
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
Expand All @@ -28,7 +43,9 @@ spec:
containers:
- name: gameservers-controller
image: gcr.io/agon-images/gameservers-controller:0.1
imagePullPolicy: Always
imagePullPolicy: Always # remove/set to IfNotPresent for production
env:
- name: ALWAYS_PULL_SIDECAR
value: "true"
value: "true" # set to false for production
# - name: SIDECAR # overwrite the GameServer sidecar image that is used
# value: gcr.io/agon-images/gameservers-sidecar:0.1
45 changes: 0 additions & 45 deletions pkg/apis/stable/v1alpha1/crd.go

This file was deleted.