Loading cmd/felis/bootstrap_assets.go +9 −2 Changes for cmd/felis/bootstrap_assets.go: 9 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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 Loading cmd/felis/run_test.go +19 −0 Changes for cmd/felis/run_test.go: 19 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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 { Loading deploy/bootstrap.sh +8 −1 Changes for deploy/bootstrap.sh: 8 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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=" Loading Loading @@ -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}" Loading deploy/bootstrap_test.sh +13 −1 Changes for deploy/bootstrap_test.sh: 13 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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" Loading internal/fileedit/k8sjobs.go +0 −19 Changes for internal/fileedit/k8sjobs.go: 0 added lines, 19 removed lines. Original line number Diff line number Diff line Loading @@ -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 Loading Loading
cmd/felis/bootstrap_assets.go +9 −2 Changes for cmd/felis/bootstrap_assets.go: 9 added lines, 2 removed lines. Original line number Diff line number Diff line Loading @@ -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 { Loading @@ -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 Loading
cmd/felis/run_test.go +19 −0 Changes for cmd/felis/run_test.go: 19 added lines, 0 removed lines. Original line number Diff line number Diff line Loading @@ -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 { Loading
deploy/bootstrap.sh +8 −1 Changes for deploy/bootstrap.sh: 8 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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=" Loading Loading @@ -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}" Loading
deploy/bootstrap_test.sh +13 −1 Changes for deploy/bootstrap_test.sh: 13 added lines, 1 removed line. Original line number Diff line number Diff line Loading @@ -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" Loading Loading @@ -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" Loading
internal/fileedit/k8sjobs.go +0 −19 Changes for internal/fileedit/k8sjobs.go: 0 added lines, 19 removed lines. Original line number Diff line number Diff line Loading @@ -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 Loading