Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions controlplane/serverconfig/paper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package serverconfig

import (
"fmt"

"github.com/goccy/go-yaml"
"github.com/spacechunks/explorer/controlplane/blob"
)

/*
proxies:
bungee-cord:
online-mode: true
proxy-protocol: false
velocity:
enabled: false
online-mode: true
secret: ""
*/

type paperGlobal struct {
Proxies proxiesConfig `json:"proxies"`
}

type proxiesConfig struct {
ProxyProtocol bool `json:"proxy-protocol"`
Velocity struct {
Enabled bool `json:"enabled"`
OnlineMode bool `json:"online-mode"`
Secret string `json:"secret"`
}
}

func sanatizePaperGlobal(data []byte) ([]byte, error) {
var global paperGlobal
if err := yaml.Unmarshal(data, &blob.Object{}); err != nil {
return nil, fmt.Errorf("unmarshal: %w", err)
}

global.Proxies.ProxyProtocol = false

global.Proxies.Velocity.Enabled = true
global.Proxies.Velocity.OnlineMode = true
global.Proxies.Velocity.Secret = ""

ret, err := yaml.Marshal(global)
if err != nil {
return nil, fmt.Errorf("marshal: %w", err)
}

return ret, nil
}
46 changes: 46 additions & 0 deletions controlplane/serverconfig/paper_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package serverconfig

import (
"testing"

"github.com/goccy/go-yaml"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
)

func TestPaperConfigAdjustments(t *testing.T) {
input := `
proxies:
bungee-cord:
online-mode: true
proxy-protocol: true
velocity:
enabled: false
online-mode: false
secret: "blalala"
`
expectedCfg := paperGlobal{
Proxies: proxiesConfig{
ProxyProtocol: false,
Velocity: struct {
Enabled bool `json:"enabled"`
OnlineMode bool `json:"online-mode"`
Secret string `json:"secret"`
}{
Enabled: true,
OnlineMode: true,
Secret: "",
},
},
}

expectedYaml, err := yaml.Marshal(expectedCfg)
require.NoError(t, err)

actual, err := sanatizePaperGlobal([]byte(input))
require.NoError(t, err)

if d := cmp.Diff(string(expectedYaml), string(actual)); d != "" {
t.Fatalf("mismatch (-want +got):\n%s", d)
}
}
60 changes: 60 additions & 0 deletions controlplane/serverconfig/sanatize.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package serverconfig

import (
"fmt"
"io/fs"
"os"
)

type sanatize func(data []byte) ([]byte, error)

var sanatizers map[string]sanatize

func init() {
sanatizers = map[string]sanatize{
"server.properties": sanatizeServerProperties,
"config/paper-global.yml": sanatizePaperGlobal,
}
}

func SanitizeConfigs(root *os.Root) error {
if err := fs.WalkDir(root.FS(), ".", func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}

if d.IsDir() {
return nil
}

sanatize, ok := sanatizers[path]
if !ok {
return nil
}

data, err := root.ReadFile(path)
if err != nil {
return fmt.Errorf("failed to read file: %w", err)
}

sanatized, err := sanatize(data)
if err != nil {
return fmt.Errorf("sanatize file %s: %w", path, err)
}

info, err := d.Info()
if err != nil {
return fmt.Errorf("file info %s: %w", path, err)
}

if err := root.WriteFile(path, sanatized, info.Mode()); err != nil {
return fmt.Errorf("write file %s: %w", path, err)
}

return nil
}); err != nil {
return err
}

return nil
}
89 changes: 89 additions & 0 deletions controlplane/serverconfig/sanatize_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package serverconfig_test

import (
"os"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/spacechunks/explorer/controlplane/serverconfig"
"github.com/stretchr/testify/require"
)

func TestSanatizeConfigs(t *testing.T) {
root, err := os.OpenRoot(t.TempDir())
require.NoError(t, err)

paperGlobal := `
proxies:
bungee-cord:
online-mode: true
proxy-protocol: true
velocity:
enabled: false
online-mode: false
secret: "blalala"
`

err = root.Mkdir("config", os.ModePerm)
require.NoError(t, err)

err = root.WriteFile("config/paper-global.yml", []byte(paperGlobal), os.ModePerm)
require.NoError(t, err)

properties := `
#Minecraft server properties
#Mon Mar 09 17:21:18 CET 2026
log-ips=true
management-server-allowed-origins=
management-server-enabled=false
management-server-host=1.1.1.1
management-server-port=1337
management-server-secret=wrong
management-server-tls-enabled=false
online-mode=true
server-ip=
server-port=1337
use-native-transport=true
`

err = root.WriteFile("server.properties", []byte(properties), os.ModePerm)
require.NoError(t, err)

err = serverconfig.SanitizeConfigs(root)
require.NoError(t, err)

expectedPaperGlobal := `proxies:
proxy-protocol: false
velocity:
enabled: true
online-mode: true
secret: ""
`

expectedProperties := `log-ips = false
management-server-allowed-origins = *
management-server-enabled = true
management-server-host = localhost
management-server-port = 26656
management-server-secret = change-me-later
management-server-tls-enabled = false
online-mode = false
server-ip = 0.0.0.0
server-port = 25565
use-native-transport = true
`

actualPaperGlobal, err := root.ReadFile("config/paper-global.yml")
require.NoError(t, err)

actualProperties, err := root.ReadFile("server.properties")
require.NoError(t, err)

if d := cmp.Diff(expectedPaperGlobal, string(actualPaperGlobal)); d != "" {
t.Fatalf("mismatch (-want +got):\n%s", d)
}

if d := cmp.Diff(expectedProperties, string(actualProperties)); d != "" {
t.Fatalf("mismatch (-want +got):\n%s", d)
}
}
36 changes: 36 additions & 0 deletions controlplane/serverconfig/vanilla.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package serverconfig

import (
"fmt"

"github.com/magiconair/properties"
)

func sanatizeServerProperties(data []byte) ([]byte, error) {
props, err := properties.LoadString(string(data))
if err != nil {
return nil, fmt.Errorf("parse properties: %w", err)
}

vals := map[string]any{
"server-ip": "0.0.0.0",
"server-port": 25565,
"management-server-allowed-origins": "*",
"management-server-enabled": true,
"management-server-host": "localhost",
"management-server-port": 26656,
"management-server-secret": "change-me-later",
"management-server-tls-enabled": false,
"online-mode": false,
"log-ips": false,
"use-native-transport": true,
}

for k, v := range vals {
if err := props.SetValue(k, v); err != nil {
return nil, fmt.Errorf("set %s: %w", k, err)
}
}

return []byte(props.String()), nil
}
43 changes: 43 additions & 0 deletions controlplane/serverconfig/vanilla_internal_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package serverconfig

import (
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
)

func TestMutateProperties(t *testing.T) {
input := `#Minecraft server properties
#Mon Mar 09 17:21:18 CET 2026
log-ips=true
management-server-allowed-origins=
management-server-enabled=false
management-server-host=1.1.1.1
management-server-port=1337
management-server-secret=wrong
management-server-tls-enabled=false
online-mode=true
server-ip=
server-port=1337
use-native-transport=true
`
expected := `log-ips = false
management-server-allowed-origins = *
management-server-enabled = true
management-server-host = localhost
management-server-port = 26656
management-server-secret = change-me-later
management-server-tls-enabled = false
online-mode = false
server-ip = 0.0.0.0
server-port = 25565
use-native-transport = true
`
actual, err := sanatizeServerProperties([]byte(input))
require.NoError(t, err)

if d := cmp.Diff(expected, string(actual)); d != "" {
t.Fatalf("mismatch (-want +got):\n%s", d)
}
}
12 changes: 9 additions & 3 deletions controlplane/worker/create_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/spacechunks/explorer/controlplane/chunk"
"github.com/spacechunks/explorer/controlplane/job"
"github.com/spacechunks/explorer/controlplane/resource"
"github.com/spacechunks/explorer/controlplane/serverconfig"
"github.com/spacechunks/explorer/internal/file"
"github.com/spacechunks/explorer/internal/image"
"github.com/spacechunks/explorer/internal/tarhelper"
Expand Down Expand Up @@ -152,7 +153,14 @@ func (w *CreateImageWorker) Work(ctx context.Context, riverJob *river.Job[job.Cr
return fmt.Errorf("download missing: %w", err)
}

// TODO: adjust configs
rt, err := os.OpenRoot(serverRootDir)
if err != nil {
return fmt.Errorf("open root: %w", err)
}

if err := serverconfig.SanitizeConfigs(rt); err != nil {
return fmt.Errorf("sanitize configs: %w", err)
}

// it is VERY important we specify the parent of the server root directory,
// because only paths starting INSIDE the passed directory are preserved.
Expand All @@ -162,8 +170,6 @@ func (w *CreateImageWorker) Work(ctx context.Context, riverJob *river.Job[job.Cr
return fmt.Errorf("append layer: %w", err)
}

// FIXME: if we implement users add user id to ref
// => <registry>/<userID>/<flavor-version-id>:<base|checkpoint>
ref := fmt.Sprintf("%s/%s:base", riverJob.Args.OCIRegistry, riverJob.Args.FlavorVersionID)

if err := w.imgService.Push(ctx, img, ref); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ require (
github.com/jackc/pgx/v5 v5.7.4
github.com/johannesboyne/gofakes3 v0.0.0-20250825084532-6555d310c473
github.com/lestrrat-go/jwx/v3 v3.0.12
github.com/magiconair/properties v1.8.10
github.com/peterbourgon/ff/v3 v3.4.0
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c
github.com/pkg/errors v0.9.1
Expand Down Expand Up @@ -124,7 +125,6 @@ require (
github.com/lib/pq v1.10.9 // indirect
github.com/lmittmann/tint v1.0.7 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
Expand Down
Loading