Idea: repo-manager

Why

In a world of containers, developers need to have multiple linux repos mirrored on prem for use when building or modifying images.

What

Similar to how cert-manager works with providers to extend functionality, repo-manager can be extended to mirror additional linux distros.

How

repo-manager provides an operator-type controller which watches for the CRD type ‘mirror.aarr.xyz’ & manages for each repo mirror:

  • the deployment of a pod for mirroring
  • a pvc for each pod
  • the increasing of the pvc size as needed
  • ingress configuration to reach each repo using a subpath http(s)://mirror.<fqdn>/<path>
  • a status using kubectl via displaying relevant CRDs
  • mapping of a ca-bundle
  • repo-specific settings

Also

  • an overall web interface
  • settings which apply to all repo mirrors

gge ingresses, a view into the world of kubernetes

(gge) This is so fun, taking advantage of kubernetes cronjobs …

The generic game engine will host tournaments.

I was planning on daily and weekly tournaments that everyone can participate in, but also allow folks to create their own.  Figured I might be able to take care of scheduling the tournaments using something in kubernetes and I was not disappointed!

The workflow goes like this:

  • create a tournament instance
  • create a cronjob with the tournament start time
  • when the cronjob starts, it creates a pod that runs curl and accesses an internal-only tournament api to start the tournament
  • tournaments will only run once by default but by setting a value will repeat on the cronjob schedule

Just have to make sure to delete the cronjob along with the tournament.  If someone were to delete the tournament using kubectl there is a chance of an orphaned cronjob (oh no) if the tournament controller isn’t running to catch it, otherwise the tournament controller will receive a DELETE event and go ahead and delete the cronjob.  Will have to run a cleanup process now and then to look for orphaned cronjobs, wonder if there might be a convenient way to do that???

Generic Boardgame Game Engine is coming along, its playable …

Putting this together was so much fun, and surprisingly quick to implement.
Still got a few more features to add, let’s just call this the teaser trailer …

$ k get all
NAME                                                               READY   STATUS    RESTARTS   AGE
pod/gge-controller-tournament-single-elimination-db6b6f474-fxg2c   1/1     Running   0          3d2h
pod/gge-game-77767987b5-z6kt8                                      1/1     Running   0          2d9h
pod/gge-tournament-6557567558-k4hfl                                1/1     Running   0          2d9h
pod/gge-gateway-c49fb8549-6wwc6                                    1/1     Running   0          2d9h
pod/gge-game-template-79c4bf84fc-54rng                             1/1     Running   0          2d6h
pod/gge-tournament-template-854f5c4475-txvmb                       1/1     Running   0          2d6h
pod/gge-controller-game-tic-tac-toe-576cd5d665-b4fzc               1/1     Running   0          2d3h
pod/gge-auth-5b4b8bb885-lp7j7                                      1/1     Running   0          2d2h

NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/gge-auth                  ClusterIP   10.97.159.55     <none>        80/TCP    4d1h
service/gge-gateway               ClusterIP   10.96.99.201     <none>        80/TCP    4d1h
service/gge-game                  ClusterIP   10.100.145.200   <none>        80/TCP    4d1h
service/gge-tournament            ClusterIP   10.109.47.239    <none>        80/TCP    2d12h
service/gge-tournament-template   ClusterIP   10.102.242.111   <none>        80/TCP    2d12h
service/gge-game-template         ClusterIP   10.102.177.107   <none>        80/TCP    2d11h

NAME                                                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/gge-controller-tournament-single-elimination   1/1     1            1           3d5h
deployment.apps/gge-game                                       1/1     1            1           4d1h
deployment.apps/gge-tournament                                 1/1     1            1           2d12h
deployment.apps/gge-gateway                                    1/1     1            1           4d1h
deployment.apps/gge-game-template                              1/1     1            1           2d11h
deployment.apps/gge-tournament-template                        1/1     1            1           2d12h
deployment.apps/gge-controller-game-tic-tac-toe                1/1     1            1           3d4h
deployment.apps/gge-auth                                       1/1     1            1           4d1h

NAME                                                                     DESIRED   CURRENT   READY   AGE
replicaset.apps/gge-controller-tournament-single-elimination-db6b6f474   1         1         1       3d5h
replicaset.apps/gge-game-77767987b5                                      1         1         1       4d1h
replicaset.apps/gge-tournament-6557567558                                1         1         1       2d12h
replicaset.apps/gge-gateway-c49fb8549                                    1         1         1       4d1h
replicaset.apps/gge-game-template-79c4bf84fc                             1         1         1       2d11h
replicaset.apps/gge-tournament-template-854f5c4475                       1         1         1       2d12h
replicaset.apps/gge-controller-game-tic-tac-toe-576cd5d665               1         1         1       3d4h
replicaset.apps/gge-auth-5b4b8bb885                                      1         1         1       4d1h

NAME                                         ENABLED   SHORT                LONG                 PATH
tournament.gge.aarr.xyz/single-elimination   true      single-elimination   Single Elimination   /tournament/single-elmination
tournament.gge.aarr.xyz/double-elimination   true      double-elimination   Double Elimination   /tournament/double-elmination
tournament.gge.aarr.xyz/round-robin          true      round-robin          Round-Robin          /tournament/round-robin

NAME                             ENABLED   SHORT          LONG           PATH
game.gge.aarr.xyz/connect-four   true      connect-four   Connect Four   /game/connect-four
game.gge.aarr.xyz/2048           true      2048           2048           /game/2048
game.gge.aarr.xyz/reversi        true      reversi        Reversi        /game/reversi
game.gge.aarr.xyz/tic-tac-toe    true      tic-tac-toe    Tic-Tac-Toe    /game/tic-tac-toe
game.gge.aarr.xyz/tripletown     true      tripletown     Triple Town    /game/tripletown

Redesigning gge (generic game engine), multi-player game lifecycle management, using kubernetes (for ai clients)

Am planning a controller to process custom resource definitions which hold all data.  By using this method a separate standalone database will not be needed, and the solution can scale as much as desired by increasing resources of the cluster itself.  Thousands of games?  Millions of games?  And if there isn’t really a limit, what’s performance going to be like?  These scaling answers must be investigated.

Besides the above, webapis, REST, OIDC, and ingresses mapped to appropriate paths will provide the infrastructure.  Looking forward to experimenting more with scaling and high-availability methods provided by kubernetes.

Sure would be nice to work on open-source 100% of the time, wonder if there might be a way to make that happen …

Initial thoughts …

use cases:
- player 0 is always game controller (can do things with items)
  - 2 players are 1,2
  - 4 players are 1,2,3,4
- 2 player games
- 4 player games
- invite rejected
- invite accepted
- start game once enough players have joined
- send notice:
  - game has started
  - plays which have occured
  - player finished their turn (if not real time strategy)
  - if play was not allowed
maybe not:
- define a unit as unique?


crds:
---
boardgame.gge.aarr.xyz
invite.gge.aarr.xyz
event.gge.aarr.xyz ?

tic-tac-toe.game.gge.aarr.xyz
tic-tac-toe.play.gge.aarr.xyz (a controller for each game to process just that game)
reversi.game.gge.aarr.xyz
reversi.play.gge.aarr.xyz (a controller for each game to process just that game)

tournament.gge.aarr.xyz
- single-elimination.tournament.gge.aarr.xyz
- double-elimination.tournament.gge.aarr.xyz


[crd: boardgame.gge.aarr.xyz]
---
short: string
long: string
enabled: bool
path: string

[tic-tac-toe.boardgame.gge.aarr.xyz] (example instance)
---
short: "tic-tac-toe"
long: "Tic-Tac-Toe"
enabled: true
path: "/api/game/tic-tac-toe"


[crd: invite.gge.aarr.xyz]
---
game: string
user: string

[tic-tac-toe_<timestamp>.invite.gge.aarr.xyz] (example instance)
---
game: tic-tac-toe_<timestamp>
user: asdf <user being invited>


[crd: tic-tac-toe.game.gge.aarr.xyz]
---
owner: string
description: tic-tac-toe
is_invite_only: bool
is_public_view: bool
turn_type: string
allowed_num_players:
- <list>
invites:
- <list>{user: aaa, status: accepted}
- <list>{user: bbb, status: accepted}
grids:
- {id: 0, width: 3, height: 3}
players:
- <list>{id: 1, user: aaa}
- <list>{id: 2, user: bbb}
units: (available units in crd)
- id: 0
  desc: string
  ascii: string of length 1
  imgsrc: <url>string
  players:
  - 1 (list of players allowed to use this unit)
  actions:
  - add (list of actions which may be performed)
  attrs:
  - (optional) list of name/value attributes
plays:
- <list>

[tic-tac-toe_<timestamp>.game.gge.aarr.xyz] (example instance)
---
owner: tloyd
is_invite_only: true
is_public_view: true
turn_type: round_robin
allowed_num_players:
- 2
invites:
- {user: aaa, status: accepted}
- {user: bbb, status: accepted}
players:
- {id: 1, user: aaa}
- {id: 2, user: bbb}
items: (units in play)
- {id: 0, unit: <id>, grid: 0, y: 1, x: 1, level: 0, player: 0}
- {id: 1, unit: <id>, grid: 0, y: 0, x: 0, level: 0, player: 1}
plays:
- id: 0
  player: 1
  plays:
  - {id: 0, action: add, grid: 0, y: 1, x: 1, level: 0}
- id: 1
  player: 2
  plays:
  - {id: 0, action: add, grid: 0, y: 0, x: 0, level: 0}


[tic-tac-toe.play.gge.aarr.xyz]
---
game: string
player: <id>
plays:
- <list>{id: 0, action: add, grid: 0, y: 1, x: 1, level: 0, unit: <id>}

[tic-tac-toe_<timestamp>.tic-tac-toe.play.gge.aarr.xyz] (example instance)
---
game: tic-tac-toe_<timestamp>
player: 1
plays:
- <list>{id: 0, action: add, grid: 0, y: 1, x: 1, level: 0, unit: <id>}