fix(ci): preserve installer compatibility with older releases

This commit is contained in:
Lemon-miaow committed 2026-10-05 00:23:35 +08:00
1 parent 30c37617c7
commit 862ff3929f
5 files changed
+49 -23

No files matched your search

+9 -2
View File
@@ -9,10 +9,17 @@ import (
func cmdBootstrapAssets(args []string, stdout, stderr io.Writer) int {
if len(args) != 1 {
fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack")
fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack|config-keys")
return 2
}
switch args[0] {
case "config-keys":
// Optional keys the installer may emit; older binaries reject this verb.
_, err := fmt.Fprintln(stdout, "velocity.game_version")
if err != nil {
fmt.Fprintf(stderr, "felis bootstrap-assets: write: %v\n", err)
return 1
}
case "crd":
crd, err := felis.MinecraftServerCRD()
if err != nil {
@@ -32,7 +39,7 @@ func cmdBootstrapAssets(args []string, stdout, stderr io.Writer) int {
return 1
}
default:
fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack")
fmt.Fprintln(stderr, "felis bootstrap-assets: usage: felis bootstrap-assets crd|game-stack|config-keys")
return 2
}
return 0
+19
View File
@@ -5,8 +5,27 @@ import (
"os"
"strings"
"testing"
"github.com/BurntSushi/toml"
"felis.lolicon.best/internal/config"
)
func TestBootstrapConfigKeys(t *testing.T) {
var out, errBuf bytes.Buffer
if code := run([]string{"bootstrap-assets", "config-keys"}, &out, &errBuf); code != 0 {
t.Fatalf("exit code = %d: %s", code, errBuf.String())
}
var cfg config.Config
meta, err := toml.Decode(strings.TrimSpace(out.String())+` = "26.3"`, &cfg)
if err != nil || len(meta.Undecoded()) != 0 {
t.Fatalf("advertised config key is unsupported: %v, undecoded: %v", err, meta.Undecoded())
}
if cfg.Velocity.GameVersion != "26.3" {
t.Fatalf("advertised key did not set the game version: %q", cfg.Velocity.GameVersion)
}
}
func TestRunNoArgsPrintsUsage(t *testing.T) {
var out, errBuf bytes.Buffer
if code := run(nil, &out, &errBuf); code != 2 {
+8 -1
View File
@@ -4707,6 +4707,13 @@ offsite_enabled() {
# database password.
write_felis_toml() {
local target="$1" db_addr="$2" deployment="${3:-}" deployment_line="" smtp_block auth_body auth_source_blocks registry_block archive_block offsite_section
local config_keys game_version_line=""
# main's installer also installs older releases, whose strict TOML parser rejects
# newer optional keys. Ask the installed binary rather than guessing from its stamp.
config_keys="$("$HOST_BIN" bootstrap-assets config-keys 2>/dev/null || true)"
if grep -Fxq 'velocity.game_version' <<<"$config_keys"; then
game_version_line="game_version = \"${MC_VERSION:-}\""
fi
if [ -n "$deployment" ]; then
# Starts with the newline that ends the url line, so the pod copy has no blank line there.
deployment_line="
@@ -4762,7 +4769,7 @@ login_image = "${FELIS_LIMBO_IMAGE}"
lobby_image = "${FELIS_LOBBY_IMAGE}"
# The public port players connect on; the panel shows it in server addresses.
game_port = ${FELIS_GAME_PORT}
game_version = "${MC_VERSION:-}"
${game_version_line}
[registry]
url = "${REGISTRY_URL}"
+13 -1
View File
@@ -2042,11 +2042,16 @@ run_write() { # out-file [state-dir] [database-deployment]; under the installer'
[ -z "${CAT_FAILS:-}" ] || cat() { head -c 40; return 1; }
persisted_smtp_block() { :; }
persisted_auth_source_blocks() { :; }
felis() {
[ "$*" = "bootstrap-assets config-keys" ] || return 2
[ "${OLD_CONFIG:-0}" != 1 ] || return 2
printf "%s\n" velocity.game_version
}
. "$FNFILE"
FELIS_ROOT_DOMAIN=r.example.com DB_USER=u DB_PASSWORD=p DB_NAME=d MINECRAFT_NS=minecraft \
FELIS_EGRESS_MODE=nodeport FELIS_LIMBO_IMAGE=li FELIS_LOBBY_IMAGE=lo FELIS_GAME_PORT=25570 MC_VERSION=26.3 \
REGISTRY_URL=registry.felis.svc:5000 BUILD_NS=felis-build FELIS_ARCHIVE_LOCAL_PATH=/a \
FELIS_OFFSITE_BUCKET= write_felis_toml "$OUT_TOML" 127.0.0.1:15432 "$DEPLOY"'
HOST_BIN=felis FELIS_OFFSITE_BUCKET= write_felis_toml "$OUT_TOML" 127.0.0.1:15432 "$DEPLOY"'
}
run_write "$rdir/out.toml"
@@ -2086,6 +2091,13 @@ expect "a re-run carries the scheduled backup retention" 'scheduled_retention =
expect "the archive mount stays installer-owned" 'local_path = "/a"' "$out"
expect "the panel learns the public game port" 'game_port = 25570' "$out"
expect "the panel learns the built login protocol" 'game_version = "26.3"' "$out"
(OLD_CONFIG=1 run_write "$rdir/release.toml")
release_config="$(cat "$rdir/release.toml")"
case "$release_config" in
*game_version*) echo "FAIL an older binary must not receive velocity.game_version"; fails=$((fails + 1)) ;;
*) echo "PASS an older binary receives no unsupported game-version key" ;;
esac
expect "an older binary still receives the public game port" 'game_port = 25570' "$release_config"
expect "a re-run keeps the off-site bucket, set apart from the next section" '[offsite]
endpoint = "https://objects.example"
bucket = "felis-offsite"
-19
View File
@@ -157,25 +157,6 @@ func (k *K8sRunner) awaitPod(ctx context.Context, p JobParams) (*corev1.Pod, err
}
}
// podLog reads a finished Pod's log. Follow is off — the Pod has already
// terminated, so the log is complete and a follow would merely block until the
// stream closed.
func (k *K8sRunner) podLog(ctx context.Context, namespace, pod string) (string, error) {
stream, err := k.cs.CoreV1().Pods(namespace).GetLogs(pod, &corev1.PodLogOptions{
Container: containerName,
}).Stream(ctx)
if err != nil {
return "", fmt.Errorf("fileedit: read file job log: %w", err)
}
defer stream.Close()
b, err := io.ReadAll(io.LimitReader(stream, maxLogBytes))
if err != nil && !errors.Is(err, io.EOF) {
return "", fmt.Errorf("fileedit: read file job log: %w", err)
}
return string(b), nil
}
// extractResult finds the marked payload in a Pod log. It scans for the LAST line
// carrying ResultPrefix because pods/log returns stdout and stderr MERGED: a Go
// runtime warning or a libc message can appear anywhere in the stream, so the