fix(restore): replace a finished Job so retries enqueue; replicate felis-config
An E2E audit on a live install found that a FAILED restore held its deterministic Job name for the rest of the 10-minute TTL, so the next restore answered 202 'restoring' while nothing ran (ErrAlreadyExists was treated as success unconditionally). K8sJobs now inspects the colliding Job: in-flight still coalesces, finished (succeeded or failed) is deleted and replaced. The minecraft-namespace Role gains jobs:get/delete for exactly that replacement. The same audit found the backup Job mounts the felis-config Secret but the installer only provisions it in the control namespace, so every backup Job stranded on FailedMount. felis setup now replicates it into the minecraft namespace beside the service-token and forwarding secrets.
This commit is contained in:
6 files changed
+134
-27
No files matched your search
+10
-5
@@ -225,16 +225,21 @@ func provisionSystemServers(ctx context.Context, cfg *config.Config, out io.Writ
|
||||
// renamed it must replicate the Secret by hand.
|
||||
controlNS := platform.DefaultControlNamespace
|
||||
apiBaseURL := platform.InternalAPIBaseURL(controlNS)
|
||||
// Both Secrets must land in the minecraft namespace before the pods that mount
|
||||
// them are created: the service token (login authenticates to felis-api with it)
|
||||
// and the Velocity forwarding secret (every backend verifies the proxy's signed
|
||||
// handshake with it — without it the login gate would derive an OFFLINE UUID and
|
||||
// the Owner would bind the wrong Minecraft identity).
|
||||
// These Secrets must land in the minecraft namespace before the pods that
|
||||
// mount them are created: the service token (login authenticates to felis-api
|
||||
// with it), the Velocity forwarding secret (every backend verifies the proxy's
|
||||
// signed handshake with it — without it the login gate would derive an OFFLINE
|
||||
// UUID and the Owner would bind the wrong Minecraft identity), and felis-config
|
||||
// (the on-demand BACKUP Job runs in the minecraft namespace and mounts it to
|
||||
// self-record its world_backups row; without the replica the Job's volume
|
||||
// mount fails and every backup request strands in the cluster).
|
||||
secretOutcomes := []systemServerOutcome{
|
||||
ensureSecretReplica(ctx, cl, controlNS, cfg.K8s.Namespace,
|
||||
naming.ServiceTokenSecretName, naming.ServiceTokenSecretKey, "service-token"),
|
||||
ensureSecretReplica(ctx, cl, controlNS, cfg.K8s.Namespace,
|
||||
naming.ForwardingSecretName, naming.ForwardingSecretKey, "forwarding-secret"),
|
||||
ensureSecretReplica(ctx, cl, controlNS, cfg.K8s.Namespace,
|
||||
"felis-config", "felis.toml", "config"),
|
||||
}
|
||||
outcomes := ensureSystemServers(ctx, cl, cfg.K8s.Namespace, cfg.Velocity.LoginImage, cfg.Velocity.LobbyImage, apiBaseURL, cfg.Server.RootDomain, defaultPanelHostname(cfg.Server.RootDomain, cfg.Auth.PanelHostname))
|
||||
outcomes = append(secretOutcomes, outcomes...)
|
||||
|
||||
Reference in new issue
Block a user