10
10
import io .fabric8 .kubernetes .api .model .ConfigMapVolumeSource ;
11
11
import io .fabric8 .kubernetes .api .model .ConfigMapVolumeSourceBuilder ;
12
12
import io .fabric8 .kubernetes .api .model .Container ;
13
+ import io .fabric8 .kubernetes .api .model .ContainerBuilder ;
13
14
import io .fabric8 .kubernetes .api .model .ContainerPort ;
14
15
import io .fabric8 .kubernetes .api .model .ContainerPortBuilder ;
15
16
import io .fabric8 .kubernetes .api .model .EnvVar ;
23
24
import io .fabric8 .kubernetes .api .model .OwnerReferenceBuilder ;
24
25
import io .fabric8 .kubernetes .api .model .PersistentVolumeClaim ;
25
26
import io .fabric8 .kubernetes .api .model .PersistentVolumeClaimBuilder ;
27
+ import io .fabric8 .kubernetes .api .model .PodSecurityContext ;
28
+ import io .fabric8 .kubernetes .api .model .PodSecurityContextBuilder ;
26
29
import io .fabric8 .kubernetes .api .model .Probe ;
27
30
import io .fabric8 .kubernetes .api .model .ProbeBuilder ;
28
31
import io .fabric8 .kubernetes .api .model .Quantity ;
@@ -86,6 +89,11 @@ public abstract class AbstractModel {
86
89
protected static final int CERTS_EXPIRATION_DAYS = 365 ;
87
90
protected static final String DEFAULT_JVM_XMS = "128M" ;
88
91
92
+ private static final String VOLUME_MOUNT_HACK_IMAGE = "busybox" ;
93
+ protected static final String VOLUME_MOUNT_HACK_NAME = "volume-mount-hack" ;
94
+ private static final Long VOLUME_MOUNT_HACK_USERID = 1001L ;
95
+ private static final Long VOLUME_MOUNT_HACK_GROUPID = 0L ;
96
+
89
97
public static final String ANCILLARY_CM_KEY_METRICS = "metrics-config.yml" ;
90
98
public static final String ANCILLARY_CM_KEY_LOG_CONFIG = "log4j.properties" ;
91
99
public static final String ENV_VAR_DYNAMIC_HEAP_FRACTION = "DYNAMIC_HEAP_FRACTION" ;
@@ -744,9 +752,11 @@ protected Service createHeadlessService(List<ServicePort> ports, Map<String, Str
744
752
protected StatefulSet createStatefulSet (
745
753
List <Volume > volumes ,
746
754
List <PersistentVolumeClaim > volumeClaims ,
755
+ List <VolumeMount > volumeMounts ,
747
756
Affinity affinity ,
748
757
List <Container > initContainers ,
749
- List <Container > containers ) {
758
+ List <Container > containers ,
759
+ boolean isOpenShift ) {
750
760
751
761
Map <String , String > annotations = new HashMap <>();
752
762
@@ -755,6 +765,25 @@ protected StatefulSet createStatefulSet(
755
765
&& ((PersistentClaimStorage ) storage ).isDeleteClaim ()));
756
766
757
767
List <Container > initContainersInternal = new ArrayList <>();
768
+ PodSecurityContext securityContext = null ;
769
+ // if a persistent volume claim is requested and the running cluster is a Kubernetes one
770
+ // there is an hack on volume mounting which needs an "init-container"
771
+ if (this .storage instanceof PersistentClaimStorage && !isOpenShift ) {
772
+ String chown = String .format ("chown -R %d:%d %s" ,
773
+ AbstractModel .VOLUME_MOUNT_HACK_USERID ,
774
+ AbstractModel .VOLUME_MOUNT_HACK_GROUPID ,
775
+ volumeMounts .get (0 ).getMountPath ());
776
+ Container initContainer = new ContainerBuilder ()
777
+ .withName (AbstractModel .VOLUME_MOUNT_HACK_NAME )
778
+ .withImage (AbstractModel .VOLUME_MOUNT_HACK_IMAGE )
779
+ .withVolumeMounts (volumeMounts .get (0 ))
780
+ .withCommand ("sh" , "-c" , chown )
781
+ .build ();
782
+ initContainersInternal .add (initContainer );
783
+ securityContext = new PodSecurityContextBuilder ()
784
+ .withFsGroup (AbstractModel .VOLUME_MOUNT_HACK_GROUPID )
785
+ .build ();
786
+ }
758
787
// add all the other init containers provided by the specific model implementation
759
788
if (initContainers != null ) {
760
789
initContainersInternal .addAll (initContainers );
@@ -782,6 +811,7 @@ protected StatefulSet createStatefulSet(
782
811
.withNewSpec ()
783
812
.withServiceAccountName (getServiceAccountName ())
784
813
.withAffinity (affinity )
814
+ .withSecurityContext (securityContext )
785
815
.withInitContainers (initContainersInternal )
786
816
.withContainers (containers )
787
817
.withVolumes (volumes )
0 commit comments