Skip to content

Commit

Permalink
install.yaml to install Agon.
Browse files Browse the repository at this point in the history
Install CRD and Controller via yaml is cleaner,
and also make it far easier to uninstall (kubectl delete -f)

Added some documentation around installation, etc.

Closes #17
  • Loading branch information
markmandel committed Dec 8, 2017
1 parent 14cb4d4 commit fb11d70
Show file tree
Hide file tree
Showing 7 changed files with 76 additions and 133 deletions.
13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
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
2 changes: 1 addition & 1 deletion build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ 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)

# Generate the gRPC sidecar Server
# Generate the gRPC sidecar Server and Client
gen-gameservers-sidecar-grpc: ensure-image
docker run --rm $(common_mounts) --entrypoint="/root/gen-grpc-go.sh" $(TAG)

Expand Down
46 changes: 32 additions & 14 deletions build/README.md
Original file line number Diff line number Diff line change
@@ -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 is
built from the Dockerfile based image 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
Original file line number Diff line number Diff line change
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 @@ -383,28 +379,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 @@ -413,7 +392,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
Original file line number Diff line number Diff line change
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 @@ -579,13 +540,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
22 changes: 19 additions & 3 deletions gameservers/controller/deployment.yaml → install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,21 @@
# 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: 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 +42,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.

0 comments on commit fb11d70

Please sign in to comment.