Merge branch 'add-agones'

This commit is contained in:
Daniel Oliveira
2021-01-20 20:06:59 +01:00
4 changed files with 234 additions and 36 deletions

2
.gitignore vendored
View File

@ -16,3 +16,5 @@ vendor/
bin/ bin/
.idea .idea
.envrc
.infrastructure

View File

@ -3,7 +3,7 @@ package server
import ( import (
"context" "context"
"fmt" "fmt"
"log" "github.com/criticalstack/quake-kube/pkg/extensions"
"net/url" "net/url"
"time" "time"
@ -15,8 +15,6 @@ import (
quakeserver "github.com/criticalstack/quake-kube/internal/quake/server" quakeserver "github.com/criticalstack/quake-kube/internal/quake/server"
httputil "github.com/criticalstack/quake-kube/internal/util/net/http" httputil "github.com/criticalstack/quake-kube/internal/util/net/http"
"github.com/criticalstack/quake-kube/public" "github.com/criticalstack/quake-kube/public"
sdk "agones.dev/agones/sdks/go"
) )
var opts struct { var opts struct {
@ -56,37 +54,6 @@ func NewCommand() *cobra.Command {
return err return err
} }
if opts.WithAgones {
log.Println("starting Agones SDK client")
s, err := sdk.NewSDK()
if err != nil {
return errors.Wrap(err, "Agones SDK could not be initialized")
}
if err := s.Ready(); err != nil {
log.Println("failed to make the server Ready")
}
go func() {
tick := time.Tick(2 * time.Second)
maxAttempts := 0
for {
if err := s.Health(); err != nil {
if maxAttempts > 5 {
log.Fatalf("Could not send health ping: %v", err)
}
maxAttempts++
}
select {
case <-ctx.Done():
log.Print("Stopped health pings")
return
case <-tick:
}
}
}()
}
go func() { go func() {
s := quakeserver.Server{ s := quakeserver.Server{
Dir: opts.AssetsDir, Dir: opts.AssetsDir,
@ -94,8 +61,16 @@ func NewCommand() *cobra.Command {
ConfigFile: opts.ConfigFile, ConfigFile: opts.ConfigFile,
Addr: opts.ServerAddr, Addr: opts.ServerAddr,
} }
if err := s.Start(ctx); err != nil {
panic(err) if opts.WithAgones {
agones := &extensions.Agones{}
if err := agones.Start(ctx, &s); err != nil {
panic(err)
}
} else {
if err := s.Start(ctx); err != nil {
panic(err)
}
} }
}() }()

129
examples/fleet.yaml Normal file
View File

@ -0,0 +1,129 @@
---
apiVersion: v1
kind: ConfigMap
metadata:
name: quake3-server-config
data:
config.yaml: |
fragLimit: 25
timeLimit: 15m
bot:
minPlayers: 3
game:
motd: "Welcome to Critical Stack"
type: FreeForAll
forceRespawn: false
inactivity: 10m
quadFactor: 3
weaponRespawn: 3
server:
hostname: "quakekube"
maxClients: 12
password: "changeme"
commands:
- addbot sarge 2
maps:
- name: q3dm7
type: FreeForAll
timeLimit: 10m
- name: q3dm17
type: FreeForAll
- name: q3wctf1
type: CaptureTheFlag
captureLimit: 8
- name: q3tourney2
type: Tournament
- name: q3wctf3
type: CaptureTheFlag
captureLimit: 8
- name: ztn3tourney1
type: Tournament
---
apiVersion: "agones.dev/v1"
kind: Fleet
metadata:
name: octops
labels:
cluster: gke-1.17
region: us-east-1
spec:
replicas: 1
template:
metadata:
labels:
cluster: gke-1.17
region: us-east-1
annotations:
octops.io/gameserver-ingress-domain: "mydomain.com"
octops.io/terminate-tls: "true"
octops.io/issuer-tls-name: "selfsigned-issuer"
spec:
players:
# Set initial player capacity if using PlayerTracking Alpha()
initialCapacity: 100
container: gameserver
ports:
- name: default
containerPort: 8081
protocol: TCP
# Disable should be false if the flag --with-agones=false
# health:
# disabled: true
template:
spec:
containers:
- name: gameserver
imagePullPolicy: Always
image: octops/quake:latest
command:
- q3
- server
- --config=/config/config.yaml
- --content-server=http://127.0.0.1:9090
- --agree-eula
- --client-addr=0.0.0.0:8081
- --with-agones
ports:
- containerPort: 8081
readinessProbe:
tcpSocket:
port: 8081
initialDelaySeconds: 15
periodSeconds: 5
resources:
requests:
memory: "1Gi"
cpu: "0.5"
limits:
memory: "2Gi"
cpu: "1"
volumeMounts:
- name: quake3-server-config
mountPath: /config
- name: quake3-content
mountPath: /assets
- name: content-server
imagePullPolicy: Always
image: octops/quake:latest
command:
- q3
- content
- --seed-content-url=http://content.quakejs.com
ports:
- containerPort: 9090
resources:
requests:
memory: "1Gi"
cpu: "0.5"
limits:
memory: "2Gi"
cpu: "1"
volumeMounts:
- name: quake3-content
mountPath: /assets
volumes:
- name: quake3-server-config
configMap:
name: quake3-server-config
- name: quake3-content
emptyDir: {}

View File

@ -0,0 +1,92 @@
package extensions
import (
sdk "agones.dev/agones/sdks/go"
"context"
quakenet "github.com/criticalstack/quake-kube/internal/quake/net"
quakeserver "github.com/criticalstack/quake-kube/internal/quake/server"
"github.com/pkg/errors"
"log"
"time"
)
type Agones struct {
Server *quakeserver.Server
sdk *sdk.SDK
}
func (a *Agones) Start(ctx context.Context, server *quakeserver.Server) error {
if err := a.InitSdk(); err != nil {
return err
}
a.Server = server
go a.StartHeathCheck(ctx)
go a.TrackStatus(ctx)
if err := server.Start(ctx); err != nil {
return errors.Wrap(err, "failed to start server")
}
return nil
}
func (a *Agones) InitSdk() error {
log.Println("[Agones] starting Agones SDK client")
s, err := sdk.NewSDK()
if err != nil {
return err
}
a.sdk = s
return nil
}
func (a *Agones) StartHeathCheck(ctx context.Context) {
tick := time.Tick(2 * time.Second)
maxAttempts := 0
for {
if err := a.sdk.Health(); err != nil {
if maxAttempts > 5 {
log.Fatalf("[Agones] could not send health ping: %v", err)
}
maxAttempts++
} else {
maxAttempts = 0
}
select {
case <-ctx.Done():
log.Print("[Agones] stopped health pings")
return
case <-tick:
}
}
}
func (a *Agones) TrackStatus(ctx context.Context) {
tick := time.Tick(5 * time.Second)
for {
if status, err := quakenet.GetStatus(a.Server.Addr); err == nil {
if err != nil {
log.Printf("[Agones] failed to get status from server: %s", err.Error())
continue
}
for _, p := range status.Players {
log.Printf("[Agones] player: %s", p.Name)
if _, err := a.sdk.Alpha().PlayerConnect(p.Name); err != nil {
log.Printf("[Agones] failed to register player: %s", err.Error())
}
}
log.Println("[Agones] status checked")
}
select {
case <-ctx.Done():
log.Print("[Agones] stopped status checks")
return
case <-tick:
}
}
}