Unverified Commit e4f2cff5 authored by Lemon-miaow's avatar Lemon-miaow
Browse files

fix(manifests): render the retention reaper CronJob into the Minecraft namespace

A Pod can only mount PVCs from its own namespace; the CronJob referenced the
minecraft-namespace backup PVC while being rendered under ControlNamespace, so
it could never schedule — live drill: FailedScheduling 'persistentvolumeclaim
felis-backups not found'. The reaper Role/RoleBinding were already
minecraft-scoped (the objects it touches live there), so the CronJob was the
odd one out. The minecraft felis-config replica (felis setup, backup Job fix)
supplies its config mount.
parent 0414913b
Loading
Loading
Loading
Loading
+5 −3
Changes for internal/platform/identities.go: 5 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -66,9 +66,11 @@ const (
// Params parameterises the install bundle. Namespaces and the registry location
// have safe defaults; VelocityCIDRs has none — see the field comment.
type Params struct {
	// ControlNamespace is where felis-api/operator/reaper run. Their SAs live here
	// and the RoleBindings' subjects reference them here, even though the Roles
	// they bind to live in the minecraft (and build) namespaces.
	// ControlNamespace is where felis-api/operator run. All three SAs live here and
	// the RoleBindings' subjects reference them here, even though the Roles they bind
	// to live in the minecraft (and build) namespaces. The reaper CronJob alone runs
	// in the Minecraft namespace, because a Pod can only mount PVCs from its own
	// namespace and its backup PVC is provisioned there.
	ControlNamespace string
	// MinecraftNamespace is where MinecraftServer workloads, their RCON Secrets,
	// and their world PVCs live. All three identities' minecraft-scoped Roles, and
+8 −1
Changes for internal/platform/workloads.go: 8 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -473,7 +473,14 @@ func reaperCronJob(p Params) *batchv1.CronJob {

	return &batchv1.CronJob{
		TypeMeta: metav1.TypeMeta{APIVersion: "batch/v1", Kind: "CronJob"},
		ObjectMeta: metav1.ObjectMeta{Name: SAReaper, Namespace: p.ControlNamespace, Labels: labels},
		// The CronJob lives in the MINECRAFT namespace: a Pod can only mount PVCs
		// from its own namespace and the backup PVC is provisioned there alongside
		// the backup Jobs. Placed under ControlNamespace it could never schedule
		// (FailedScheduling: persistentvolumeclaim not found) in any stock install;
		// the reaper Role/RoleBinding were already minecraft-scoped for the same
		// reason, and the minecraft felis-config replica (felis setup) supplies the
		// config mount.
		ObjectMeta: metav1.ObjectMeta{Name: SAReaper, Namespace: p.MinecraftNamespace, Labels: labels},
		Spec: batchv1.CronJobSpec{
			Schedule:                   reaperSchedule,
			ConcurrencyPolicy:          batchv1.ForbidConcurrent,
+5 −2
Changes for internal/platform/workloads_test.go: 5 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -519,8 +519,11 @@ func TestReaperCronJob_Shape(t *testing.T) {
	if cj.Name != SAReaper {
		t.Errorf("CronJob name = %q, want %q", cj.Name, SAReaper)
	}
	if cj.Namespace != p.ControlNamespace {
		t.Errorf("CronJob namespace = %q, want control ns %q", cj.Namespace, p.ControlNamespace)
	// The CronJob must sit where its PVC lives: a Pod cannot mount a PVC across
	// namespaces, and the backup PVC is provisioned in the Minecraft namespace.
	// (Rendered under ControlNamespace it failed to schedule on a live cluster.)
	if cj.Namespace != p.MinecraftNamespace {
		t.Errorf("CronJob namespace = %q, want minecraft ns %q (its backup PVC's namespace)", cj.Namespace, p.MinecraftNamespace)
	}

	spec := cj.Spec