Skip to content

Commit

Permalink
Use flocken for multiarch images
Browse files Browse the repository at this point in the history
  • Loading branch information
ChrisRx committed Apr 20, 2024
1 parent b57e37d commit 0572664
Show file tree
Hide file tree
Showing 10 changed files with 166 additions and 48 deletions.
39 changes: 14 additions & 25 deletions .github/workflows/push-image.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,32 @@ name: Push Image
on:
push:
# Sequence of patterns matched against refs/tags
branches:
- 'fix-multiarch-build'
tags:
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

jobs:
x86_64:
multiarch:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: cachix/install-nix-action@v21
- name: Build
run: |
nix build .#container
skopeo login --username "${{ github.actor }}" --password "${{ secrets.GITHUB_TOKEN }}" ghcr.io
skopeo copy docker-archive://$(readlink -f ./result) docker://ghcr.io/chrisrx/quake-kube:latest
aarch64:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- name: Checkout
uses: actions/checkout@v3
- run: sudo apt-get install -y qemu-user-static
- uses: cachix/install-nix-action@v21
- uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- uses: DeterminateSystems/nix-installer-action@v9
with:
extra_nix_config: |
system = aarch64-linux
- name: Build
run: |
nix build .#container
skopeo login --username "${{ github.actor }}" --password "${{ secrets.GITHUB_TOKEN }}" ghcr.io
skopeo copy docker-archive://$(readlink -f ./result) docker://ghcr.io/chrisrx/quake-kube:latest
extra-conf: |
extra-platforms = aarch64-linux
- uses: DeterminateSystems/magic-nix-cache-action@v2
- run: nix run --impure .#dockerManifest
env:
VERSION: "latest"
GITHUB_TOKEN: ${{ github.token }}
31 changes: 27 additions & 4 deletions cmd/q3/app/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,6 @@ func NewCommand() *cobra.Command {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

sctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
defer stop()

qs := quakeserver.Server{
Addr: opts.ServerAddr,
ConfigFile: opts.ConfigFile,
Expand All @@ -79,9 +76,24 @@ func NewCommand() *cobra.Command {
ShutdownDelay: opts.ShutdownDelay,
}
go func() {
// The main context should only cancel after the quake server is
// finished. This allows for graceful termination and the child process
// to be safely killed before exiting.
defer cancel()

if err := qs.Start(sctx); err != nil {
ctx, stop := signal.NotifyContext(ctx, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
defer stop()

registerSecondInterrupt(ctx.Done(), func() {
fmt.Println("\rCTRL+C pressed again, shutting down ...")

// We still need to call HardStop to ensure that the underlying child
// process is killed before exiting.
qs.HardStop()
os.Exit(1)
})

if err := qs.Start(ctx); err != nil {
log.Printf("quakeserver: %v\n", err)
}
}()
Expand Down Expand Up @@ -113,3 +125,14 @@ func NewCommand() *cobra.Command {
cmd.Flags().StringVar(&opts.SeedContentURL, "seed-content-url", "", "seed content from another content server")
return cmd
}

func registerSecondInterrupt(ready <-chan struct{}, fn func()) {
go func() {
<-ready
c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGINT)
<-c
signal.Stop(c)
fn()
}()
}
75 changes: 75 additions & 0 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
inputs.gomod2nix.url = "github:nix-community/gomod2nix";
inputs.gomod2nix.inputs.nixpkgs.follows = "nixpkgs";
inputs.gomod2nix.inputs.flake-utils.follows = "flake-utils";
inputs.flocken.url = "github:mirkolenz/flocken/v2";
inputs.flocken.inputs.nixpkgs.follows = "nixpkgs";

outputs = { self, nixpkgs, flake-utils, gomod2nix }:
outputs = { self, nixpkgs, flake-utils, gomod2nix, flocken }:
(flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" ]
(system:
let
Expand Down Expand Up @@ -98,6 +100,15 @@
];
config.Cmd = [ "${packages.default}/bin/q3" ];
};
legacyPackages.dockerManifest = flocken.legacyPackages.${system}.mkDockerManifest {
github = {
enable = true;
repo = "chrisrx/quake-kube";
token = builtins.getEnv "GITHUB_TOKEN";
};
version = builtins.getEnv "VERSION";
images = with self.packages; [ x86_64-linux.container aarch64-linux.container ];
};

devShells.default =
pkgs.mkShell {
Expand Down
1 change: 1 addition & 0 deletions internal/quake/server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ type ServerConfig struct {
Hostname string `name:"sv_hostname"`
MaxClients int `name:"sv_maxclients"`
Password string `name:"rconpassword"`
ListServer string `name:"sv_master1"`
}

func (c *Config) Marshal() ([]byte, error) {
Expand Down
1 change: 1 addition & 0 deletions internal/quake/server/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ seta sv_allowDownload "0"
seta sv_hostname "quakekube"
seta sv_maxclients "12"
seta rconpassword "changeme"
seta sv_master1 ""
set d0 "seta g_gametype 0 ; map q3dm7 ; set nextmap vstr d1"
set d1 "seta g_gametype 0 ; map q3dm17 ; set nextmap vstr d2"
set d2 "seta g_gametype 4 ; capturelimit 8 ; map q3wctf1 ; set nextmap vstr d3"
Expand Down
8 changes: 8 additions & 0 deletions internal/quake/server/gamefiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"log"
"os"
"path/filepath"
"strings"

contentutil "github.com/ChrisRx/quake-kube/internal/quake/content/util"
)

//go:embed EULA.txt
Expand Down Expand Up @@ -44,6 +47,11 @@ func ExtractGameFiles(dir string) error {
if err := os.WriteFile(path, data, 0644); err != nil {
return err
}
if strings.HasPrefix(hdr.Name, "linuxq3ademo") || strings.HasPrefix(hdr.Name, "linuxq3apoint") {
if err := contentutil.ExtractGzip(path, dir); err != nil {
return err
}
}
}
}
return nil
Expand Down
Binary file modified internal/quake/server/gamefiles.tar
Binary file not shown.
34 changes: 22 additions & 12 deletions internal/quake/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ type Server struct {
Dir string
WatchInterval time.Duration
ShutdownDelay time.Duration

cmd *exec.Cmd
}

func (s *Server) Start(ctx context.Context) error {
Expand All @@ -72,10 +74,10 @@ func (s *Server) Start(ctx context.Context) error {
"+set", "com_gamename", "Quake3Arena",
"+exec", "server.cfg",
}
cmd := exec.CommandContext(context.Background(), "ioq3ded", args...)
cmd.Dir = s.Dir
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
s.cmd = exec.CommandContext(context.Background(), "ioq3ded", args...)
s.cmd.Dir = s.Dir
s.cmd.Stdout = os.Stdout
s.cmd.Stderr = os.Stderr

if s.ConfigFile == "" {
cfg := Default()
Expand All @@ -86,21 +88,21 @@ func (s *Server) Start(ctx context.Context) error {
if err := os.WriteFile(filepath.Join(s.Dir, "baseq3/server.cfg"), data, 0644); err != nil {
return err
}
if err := cmd.Start(); err != nil {
if err := s.cmd.Start(); err != nil {
return err
}
return cmd.Wait()
return s.cmd.Wait()
}

if err := s.reload(); err != nil {
return err
}
if err := cmd.Start(); err != nil {
if err := s.cmd.Start(); err != nil {
return err
}

go func() {
if err := cmd.Wait(); err != nil {
if err := s.cmd.Wait(); err != nil {
log.Println(err)
}
}()
Expand Down Expand Up @@ -140,8 +142,8 @@ func (s *Server) Start(ctx context.Context) error {
}

defer func() {
if cmd.Process != nil {
if err := cmd.Process.Kill(); err != nil {
if s.cmd.Process != nil {
if err := s.cmd.Process.Kill(); err != nil {
log.Printf("couldn't kill process: %v\n", err)
}
}
Expand All @@ -154,11 +156,11 @@ func (s *Server) Start(ctx context.Context) error {
return err
}
configReloads.Inc()
if err := cmd.Restart(ctx); err != nil {
if err := s.cmd.Restart(ctx); err != nil {
return err
}
go func() {
if err := cmd.Wait(); err != nil {
if err := s.cmd.Wait(); err != nil {
log.Println(err)
}
}()
Expand Down Expand Up @@ -221,6 +223,14 @@ func (s *Server) GracefulStop() {
}
}

func (s *Server) HardStop() {
if s.cmd.Process != nil {
if err := s.cmd.Process.Kill(); err != nil {
log.Printf("couldn't kill process: %v\n", err)
}
}
}

func (s *Server) reload() error {
cfg, err := ReadConfigFromFile(s.ConfigFile)
if err != nil {
Expand Down
Loading

0 comments on commit 0572664

Please sign in to comment.