@@ -201,8 +201,9 @@ func updateKotsadmDeploymentScriptsPath(existing *appsv1.Deployment) {
201201}
202202
203203// waitForRqliteInitContainer returns an init container that polls the rqlite
204- // readiness endpoint before schemahero-plan runs. This prevents CrashLoopBackOff
205- // when kotsadm and rqlite restart simultaneously (e.g., during EC upgrades).
204+ // readiness endpoint before the rqlite-migrations init container runs. This
205+ // prevents CrashLoopBackOff when kotsadm and rqlite restart simultaneously
206+ // (e.g., during EC upgrades).
206207// Times out after 5 minutes so rqlite failures surface as a clear init error
207208// rather than an indefinite hang.
208209// Ref: https://app.shortcut.com/replicated/story/138103
@@ -226,6 +227,44 @@ func waitForRqliteInitContainer(deployOptions types.DeployOptions) corev1.Contai
226227 }
227228}
228229
230+ // rqliteMigrationsInitContainer returns an init container that applies the
231+ // rqlite schema in-process by running the kotsadm binary's `migrate
232+ // rqlite-schema` command. It replaces the schemahero-plan/apply init containers:
233+ // the schema is created by the schemahero driver lib linked into kotsadm (no
234+ // plugin binary to ship or discover), and running it as an init container keeps
235+ // the schema in place before the main container and the restore init containers.
236+ func rqliteMigrationsInitContainer (deployOptions types.DeployOptions ) corev1.Container {
237+ return corev1.Container {
238+ Image : GetAdminConsoleImage (deployOptions , "kotsadm" ),
239+ ImagePullPolicy : corev1 .PullIfNotPresent ,
240+ Name : "rqlite-migrations" ,
241+ Command : []string {"/kotsadm" , "migrate" , "rqlite-schema" },
242+ Env : []corev1.EnvVar {
243+ {
244+ Name : "RQLITE_URI" ,
245+ ValueFrom : & corev1.EnvVarSource {
246+ SecretKeyRef : & corev1.SecretKeySelector {
247+ LocalObjectReference : corev1.LocalObjectReference {
248+ Name : "kotsadm-rqlite" ,
249+ },
250+ Key : "uri" ,
251+ },
252+ },
253+ },
254+ },
255+ Resources : corev1.ResourceRequirements {
256+ Limits : corev1.ResourceList {
257+ "memory" : resource .MustParse ("100Mi" ),
258+ },
259+ Requests : corev1.ResourceList {
260+ "cpu" : resource .MustParse ("50m" ),
261+ "memory" : resource .MustParse ("50Mi" ),
262+ },
263+ },
264+ SecurityContext : k8sutil .SecureContainerContext (deployOptions .StrictSecurityContext ),
265+ }
266+ }
267+
229268func KotsadmDeployment (deployOptions types.DeployOptions ) (* appsv1.Deployment , error ) {
230269 securityContext := k8sutil .SecurePodContext (1001 , 1001 , deployOptions .StrictSecurityContext )
231270 if deployOptions .IsOpenShift {
@@ -438,14 +477,6 @@ func KotsadmDeployment(deployOptions types.DeployOptions) (*appsv1.Deployment, e
438477 }
439478
440479 volumes := []corev1.Volume {
441- {
442- Name : "migrations" ,
443- VolumeSource : corev1.VolumeSource {
444- EmptyDir : & corev1.EmptyDirVolumeSource {
445- Medium : corev1 .StorageMediumMemory ,
446- },
447- },
448- },
449480 {
450481 Name : "backup" ,
451482 VolumeSource : corev1.VolumeSource {
@@ -525,112 +556,7 @@ func KotsadmDeployment(deployOptions types.DeployOptions) (*appsv1.Deployment, e
525556 ImagePullSecrets : pullSecrets ,
526557 InitContainers : []corev1.Container {
527558 waitForRqliteInitContainer (deployOptions ),
528- {
529- Image : GetAdminConsoleImage (deployOptions , "kotsadm-migrations" ),
530- ImagePullPolicy : corev1 .PullIfNotPresent ,
531- Name : "schemahero-plan" ,
532- Args : []string {"plan" },
533- VolumeMounts : []corev1.VolumeMount {
534- {
535- Name : "migrations" ,
536- MountPath : "/migrations" ,
537- },
538- {
539- Name : "tmp" ,
540- MountPath : "/tmp" ,
541- },
542- },
543- Env : []corev1.EnvVar {
544- {
545- Name : "HOME" ,
546- Value : "/tmp" ,
547- },
548- {
549- Name : "SCHEMAHERO_DRIVER" ,
550- Value : "rqlite" ,
551- },
552- {
553- Name : "SCHEMAHERO_SPEC_FILE" ,
554- Value : "/tables" ,
555- },
556- {
557- Name : "SCHEMAHERO_OUT" ,
558- Value : "/migrations/plan.yaml" ,
559- },
560- {
561- Name : "SCHEMAHERO_URI" ,
562- ValueFrom : & corev1.EnvVarSource {
563- SecretKeyRef : & corev1.SecretKeySelector {
564- LocalObjectReference : corev1.LocalObjectReference {
565- Name : "kotsadm-rqlite" ,
566- },
567- Key : "uri" ,
568- },
569- },
570- },
571- },
572- Resources : corev1.ResourceRequirements {
573- Limits : corev1.ResourceList {
574- "memory" : resource .MustParse ("100Mi" ),
575- },
576- Requests : corev1.ResourceList {
577- "cpu" : resource .MustParse ("50m" ),
578- "memory" : resource .MustParse ("50Mi" ),
579- },
580- },
581- SecurityContext : k8sutil .SecureContainerContext (deployOptions .StrictSecurityContext ),
582- },
583- {
584- Image : GetAdminConsoleImage (deployOptions , "kotsadm-migrations" ),
585- ImagePullPolicy : corev1 .PullIfNotPresent ,
586- Name : "schemahero-apply" ,
587- Args : []string {"apply" },
588- VolumeMounts : []corev1.VolumeMount {
589- {
590- Name : "migrations" ,
591- MountPath : "/migrations" ,
592- },
593- {
594- Name : "tmp" ,
595- MountPath : "/tmp" ,
596- },
597- },
598- Env : []corev1.EnvVar {
599- {
600- Name : "HOME" ,
601- Value : "/tmp" ,
602- },
603- {
604- Name : "SCHEMAHERO_DRIVER" ,
605- Value : "rqlite" ,
606- },
607- {
608- Name : "SCHEMAHERO_DDL" ,
609- Value : "/migrations/plan.yaml" ,
610- },
611- {
612- Name : "SCHEMAHERO_URI" ,
613- ValueFrom : & corev1.EnvVarSource {
614- SecretKeyRef : & corev1.SecretKeySelector {
615- LocalObjectReference : corev1.LocalObjectReference {
616- Name : "kotsadm-rqlite" ,
617- },
618- Key : "uri" ,
619- },
620- },
621- },
622- },
623- Resources : corev1.ResourceRequirements {
624- Limits : corev1.ResourceList {
625- "memory" : resource .MustParse ("100Mi" ),
626- },
627- Requests : corev1.ResourceList {
628- "cpu" : resource .MustParse ("50m" ),
629- "memory" : resource .MustParse ("50Mi" ),
630- },
631- },
632- SecurityContext : k8sutil .SecureContainerContext (deployOptions .StrictSecurityContext ),
633- },
559+ rqliteMigrationsInitContainer (deployOptions ),
634560 {
635561 Image : GetAdminConsoleImage (deployOptions , "kotsadm" ),
636562 ImagePullPolicy : corev1 .PullIfNotPresent ,
@@ -1027,14 +953,6 @@ func KotsadmStatefulSet(deployOptions types.DeployOptions, size resource.Quantit
1027953 },
1028954 },
1029955 },
1030- {
1031- Name : "migrations" ,
1032- VolumeSource : corev1.VolumeSource {
1033- EmptyDir : & corev1.EmptyDirVolumeSource {
1034- Medium : corev1 .StorageMediumMemory ,
1035- },
1036- },
1037- },
1038956 {
1039957 Name : "backup" ,
1040958 VolumeSource : corev1.VolumeSource {
@@ -1119,112 +1037,7 @@ func KotsadmStatefulSet(deployOptions types.DeployOptions, size resource.Quantit
11191037 ImagePullSecrets : pullSecrets ,
11201038 InitContainers : []corev1.Container {
11211039 waitForRqliteInitContainer (deployOptions ),
1122- {
1123- Image : GetAdminConsoleImage (deployOptions , "kotsadm-migrations" ),
1124- ImagePullPolicy : corev1 .PullIfNotPresent ,
1125- Name : "schemahero-plan" ,
1126- Args : []string {"plan" },
1127- VolumeMounts : []corev1.VolumeMount {
1128- {
1129- Name : "migrations" ,
1130- MountPath : "/migrations" ,
1131- },
1132- {
1133- Name : "tmp" ,
1134- MountPath : "/tmp" ,
1135- },
1136- },
1137- Env : []corev1.EnvVar {
1138- {
1139- Name : "HOME" ,
1140- Value : "/tmp" ,
1141- },
1142- {
1143- Name : "SCHEMAHERO_DRIVER" ,
1144- Value : "rqlite" ,
1145- },
1146- {
1147- Name : "SCHEMAHERO_SPEC_FILE" ,
1148- Value : "/tables" ,
1149- },
1150- {
1151- Name : "SCHEMAHERO_OUT" ,
1152- Value : "/migrations/plan.yaml" ,
1153- },
1154- {
1155- Name : "SCHEMAHERO_URI" ,
1156- ValueFrom : & corev1.EnvVarSource {
1157- SecretKeyRef : & corev1.SecretKeySelector {
1158- LocalObjectReference : corev1.LocalObjectReference {
1159- Name : "kotsadm-rqlite" ,
1160- },
1161- Key : "uri" ,
1162- },
1163- },
1164- },
1165- },
1166- Resources : corev1.ResourceRequirements {
1167- Limits : corev1.ResourceList {
1168- "memory" : resource .MustParse ("100Mi" ),
1169- },
1170- Requests : corev1.ResourceList {
1171- "cpu" : resource .MustParse ("50m" ),
1172- "memory" : resource .MustParse ("50Mi" ),
1173- },
1174- },
1175- SecurityContext : k8sutil .SecureContainerContext (deployOptions .StrictSecurityContext ),
1176- },
1177- {
1178- Image : GetAdminConsoleImage (deployOptions , "kotsadm-migrations" ),
1179- ImagePullPolicy : corev1 .PullIfNotPresent ,
1180- Name : "schemahero-apply" ,
1181- Args : []string {"apply" },
1182- VolumeMounts : []corev1.VolumeMount {
1183- {
1184- Name : "migrations" ,
1185- MountPath : "/migrations" ,
1186- },
1187- {
1188- Name : "tmp" ,
1189- MountPath : "/tmp" ,
1190- },
1191- },
1192- Env : []corev1.EnvVar {
1193- {
1194- Name : "HOME" ,
1195- Value : "/tmp" ,
1196- },
1197- {
1198- Name : "SCHEMAHERO_DRIVER" ,
1199- Value : "rqlite" ,
1200- },
1201- {
1202- Name : "SCHEMAHERO_DDL" ,
1203- Value : "/migrations/plan.yaml" ,
1204- },
1205- {
1206- Name : "SCHEMAHERO_URI" ,
1207- ValueFrom : & corev1.EnvVarSource {
1208- SecretKeyRef : & corev1.SecretKeySelector {
1209- LocalObjectReference : corev1.LocalObjectReference {
1210- Name : "kotsadm-rqlite" ,
1211- },
1212- Key : "uri" ,
1213- },
1214- },
1215- },
1216- },
1217- Resources : corev1.ResourceRequirements {
1218- Limits : corev1.ResourceList {
1219- "memory" : resource .MustParse ("100Mi" ),
1220- },
1221- Requests : corev1.ResourceList {
1222- "cpu" : resource .MustParse ("50m" ),
1223- "memory" : resource .MustParse ("50Mi" ),
1224- },
1225- },
1226- SecurityContext : k8sutil .SecureContainerContext (deployOptions .StrictSecurityContext ),
1227- },
1040+ rqliteMigrationsInitContainer (deployOptions ),
12281041 {
12291042 Image : GetAdminConsoleImage (deployOptions , "kotsadm" ),
12301043 ImagePullPolicy : corev1 .PullIfNotPresent ,
0 commit comments