Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update websphere-liberty #7674

Merged
merged 1 commit into from
Mar 24, 2020
Merged

Update websphere-liberty #7674

merged 1 commit into from
Mar 24, 2020

Conversation

arthurdm
Copy link
Contributor

Bringing WebSphere Liberty to parity with Open Liberty in terms of populating a class cache during the build phase of the images.

@yosifkit
Copy link
Member

Diff:
diff --git a/websphere-liberty_20.0.0.3-full-java8-ibmjava/Dockerfile.ubuntu.ibmjava8 b/websphere-liberty_20.0.0.3-full-java8-ibmjava/Dockerfile.ubuntu.ibmjava8
index 4c6fb4a..b84b463 100644
--- a/websphere-liberty_20.0.0.3-full-java8-ibmjava/Dockerfile.ubuntu.ibmjava8
+++ b/websphere-liberty_20.0.0.3-full-java8-ibmjava/Dockerfile.ubuntu.ibmjava8
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 FROM websphere-liberty:20.0.0.3-kernel-java8-ibmjava
-
+ARG VERBOSE=false
 ARG REPOSITORIES_PROPERTIES=""
 
 RUN if [ ! -z $REPOSITORIES_PROPERTIES ]; then mkdir /opt/ibm/wlp/etc/ \
@@ -24,3 +24,9 @@ RUN if [ ! -z $REPOSITORIES_PROPERTIES ]; then mkdir /opt/ibm/wlp/etc/ \
   && chmod -R g+rwx /opt/ibm/wlp/output/*
 
 COPY --chown=1001:0 server.xml /config/
+
+# Create a new SCC layer
+RUN if [ "$OPENJ9_SCC" = "true" ]; then populate_scc.sh; fi \
+    && rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache \
+    && chown -R 1001:0 /opt/ibm/wlp/output \
+    && chmod -R g+rwx /opt/ibm/wlp/output
\ No newline at end of file
diff --git a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/Dockerfile.ubuntu.ibmjava8 b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/Dockerfile.ubuntu.ibmjava8
index 74db0c7..78ac5d7 100644
--- a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/Dockerfile.ubuntu.ibmjava8
+++ b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/Dockerfile.ubuntu.ibmjava8
@@ -14,6 +14,9 @@
 
 FROM ibmjava:8-jre
 
+ARG VERBOSE=false
+ARG OPENJ9_SCC=true
+
 LABEL org.opencontainers.image.authors="Arthur De Magalhaes, Chris Potter" \
       org.opencontainers.image.vendor="IBM" \
       org.opencontainers.image.url="http://wasdev.net" \
@@ -52,7 +55,8 @@ LABEL "ProductID"="fbf6a96d49214c0abc6a3bc5da6e48cd" \
 
 # Set Path Shortcuts
 ENV LOG_DIR=/logs \
-    WLP_OUTPUT_DIR=/opt/ibm/wlp/output 
+    WLP_OUTPUT_DIR=/opt/ibm/wlp/output \
+    OPENJ9_SCC=$OPENJ9_SCC
 
 # Configure WebSphere Liberty
 RUN /opt/ibm/wlp/bin/server create \
@@ -93,6 +97,12 @@ RUN mkdir /logs \
     && chown -R 1001:0 /home/default \
     && chmod -R g+rw /home/default
 
+# Create a new SCC layer
+RUN if [ "$OPENJ9_SCC" = "true" ]; then populate_scc.sh; fi \
+    && rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache \
+    && chown -R 1001:0 /opt/ibm/wlp/output \
+    && chmod -R g+rwx /opt/ibm/wlp/output
+
 #These settings are needed so that we can run as a different user than 1001 after server warmup
 ENV RANDFILE=/tmp/.rnd \
     IBM_JAVA_OPTIONS="-Xshareclasses:name=liberty,nonfatal,cacheDir=/output/.classCache/ ${IBM_JAVA_OPTIONS}"
diff --git a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configuration_snippets/trustDefault.xml b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configuration_snippets/trustDefault.xml
new file mode 100644
index 0000000..f49104f
--- /dev/null
+++ b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configuration_snippets/trustDefault.xml
@@ -0,0 +1,4 @@
+<server description="Default Server">
+    <ssl id="defaultSSLConfig"  trustDefaultCerts="${SEC_TLS_TRUSTDEFAULTCERTS}"/>
+    <variable name="SEC_TLS_TRUSTDEFAULTCERTS" defaultValue="false"/>
+</server>
diff --git a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configuration_snippets/truststore.xml b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configuration_snippets/truststore.xml
new file mode 100644
index 0000000..980e8ea
--- /dev/null
+++ b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configuration_snippets/truststore.xml
@@ -0,0 +1,5 @@
+<server description="Default Server">
+    <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" trustDefaultCerts="${SEC_TLS_TRUSTDEFAULTCERTS}"/>
+    <keyStore id="defaultTrustStore" location="${server.output.dir}/resources/security/trust.p12" type="PKCS12" password="PWD_TRUST" />
+    <variable name="SEC_TLS_TRUSTDEFAULTCERTS" defaultValue="false"/>
+</server>
diff --git a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configure.sh b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configure.sh
index 6579927..79b39c7 100755
--- a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configure.sh
+++ b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/configure.sh
@@ -86,8 +86,8 @@ then
   then
     # Generate the keystore.xml
     export KEYSTOREPWD=$(openssl rand -base64 32)
-    sed -i.bak "s|REPLACE|$KEYSTOREPWD|g" $SNIPPETS_SOURCE/keystore.xml
-    cp $SNIPPETS_SOURCE/keystore.xml $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+    sed "s|REPLACE|$KEYSTOREPWD|g" $SNIPPETS_SOURCE/keystore.xml > $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+    chmod g+w $SNIPPETS_TARGET_DEFAULTS/keystore.xml
   fi
 fi
 
@@ -106,7 +106,10 @@ fi
 find /opt/ibm/fixes -type f -name "*.jar"  -print0 | sort -z | xargs -0 -n 1 -r -I {} java -jar {} --installLocation $WLP_INSTALL_DIR
 #Make sure that group write permissions are set correctly after installing new features
 find /opt/ibm/wlp -perm -g=w -print0 | xargs -0 -r chmod -R g+rw
-# Server start/stop to populate the /output/workarea and make subsequent server starts faster
-/opt/ibm/wlp/bin/server start && /opt/ibm/wlp/bin/server stop && rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache /output/workarea && chmod -R g+rwx /opt/ibm/wlp/output/*
+# Create a new SCC layer
+if [ "$OPENJ9_SCC" == "true" ]
+then
+  populate_scc.sh
+fi
 #Make folder executable for a group
 find /opt/ibm/wlp -type d -perm -g=x -print0 | xargs -0 -r chmod -R g+rwx
diff --git a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/populate_scc.sh b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/populate_scc.sh
new file mode 100755
index 0000000..1eb884d
--- /dev/null
+++ b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/build/populate_scc.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+if [ "$VERBOSE" != "true" ]; then
+  exec &>/dev/null
+fi
+
+set -Eeox pipefail
+
+SCC_SIZE="80m"  # Default size of the SCC layer.
+ITERATIONS=2    # Number of iterations to run to populate it.
+TRIM_SCC=yes    # Trim the SCC to eliminate any wasted space.
+
+while getopts ":i:s:tdh" OPT
+do
+  case "$OPT" in
+    i)
+      ITERATIONS="$OPTARG"
+      ;;
+    s)
+      [ "${OPTARG: -1}" == "m" ] || ( echo "Missing m suffix." && exit 1 )
+      SCC_SIZE="$OPTARG"
+      ;;
+    t)
+      TRIM_SCC=yes
+      ;;
+    d)
+      TRIM_SCC=no
+      ;;
+    h)
+      echo \
+"Usage: $0 [-i iterations] [-s size] [-t] [-d]
+  -i <iterations> Number of iterations to run to populate the SCC. (Default: $ITERATIONS)
+  -s <size>       Size of the SCC in megabytes (m suffix required). (Default: $SCC_SIZE)
+  -t              Trim the SCC to eliminate most of the free space, if any.
+  -d              Don't trim the SCC.
+
+  Trimming enabled=$TRIM_SCC"
+      exit 1
+      ;;
+    \?)
+      echo "Unrecognized option: $OPTARG" 1>&2
+      exit 1
+      ;;
+    :)
+      echo "Missing argument for option: $OPTARG" 1>&2
+      exit 1
+      ;;
+  esac
+done
+
+# Make sure the following Java commands don't disturb our class cache until we're ready to populate it
+# by unsetting IBM_JAVA_OPTIONS if it is currently defined.
+unset IBM_JAVA_OPTIONS
+
+# Explicity create a class cache layer for this image layer here rather than allowing
+# `server start` to do it, which will lead to problems because multiple JVMs will be started.
+java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,createLayer -Xscmx$SCC_SIZE -version
+
+if [ $TRIM_SCC == yes ]
+then
+  echo "Calculating SCC layer upper bound, starting with initial size $SCC_SIZE."
+  # Populate the newly created class cache layer.
+  export IBM_JAVA_OPTIONS="-Xshareclasses:name=liberty,cacheDir=/output/.classCache/"
+  /opt/ibm/wlp/bin/server start && /opt/ibm/wlp/bin/server stop
+  # Find out how full it is.
+  unset IBM_JAVA_OPTIONS
+  FULL=`( java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,printTopLayerStats || true ) 2>&1 | awk '/^Cache is [0-9.]*% .*full/ {print substr($3, 1, length($3)-1)}'`
+  echo "SCC layer is $FULL% full. Destroying layer."
+  # Destroy the layer once we know roughly how much space we need.
+  java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,destroy || true
+  # Remove the m suffix.
+  SCC_SIZE="${SCC_SIZE:0:-1}"
+  # Calculate the new size based on how full the layer was (rounded to nearest m).
+  SCC_SIZE=`awk "BEGIN {print int($SCC_SIZE * $FULL / 100.0 + 0.5)}"`
+  # Make sure size is >0.
+  [ $SCC_SIZE -eq 0 ] && SCC_SIZE=1
+  # Add the m suffix back.
+  SCC_SIZE="${SCC_SIZE}m"
+  echo "Re-creating layer with size $SCC_SIZE."
+  # Recreate the layer with the new size.
+  java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,createLayer -Xscmx$SCC_SIZE -version
+fi
+
+# Populate the newly created class cache layer.
+export IBM_JAVA_OPTIONS="-Xshareclasses:name=liberty,cacheDir=/output/.classCache/"
+
+# Server start/stop to populate the /output/workarea and make subsequent server starts faster.
+for ((i=0; i<$ITERATIONS; i++))
+do
+  /opt/ibm/wlp/bin/server start && /opt/ibm/wlp/bin/server stop
+done
+
+rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache && chmod -R g+rwx /opt/ibm/wlp/output/*
+
+unset IBM_JAVA_OPTIONS
+# Tell the user how full the final layer is.
+FULL=`( java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,printTopLayerStats || true ) 2>&1 | awk '/^Cache is [0-9.]*% .*full/ {print substr($3, 1, length($3)-1)}'`
+echo "SCC layer is $FULL% full."
diff --git a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/runtime/docker-server.sh b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/runtime/docker-server.sh
index 5d196ad..e6fa5ea 100755
--- a/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/runtime/docker-server.sh
+++ b/websphere-liberty_20.0.0.3-kernel-java8-ibmjava/helpers/runtime/docker-server.sh
@@ -1,5 +1,66 @@
 #!/bin/bash
 
+function importKeyCert() {
+  local CERT_FOLDER="${TLS_DIR:-/etc/x509/certs}"
+  local CRT_FILE="tls.crt"
+  local KEY_FILE="tls.key"
+  local CA_FILE="ca.crt"
+  local PASSWORD=$(openssl rand -base64 32 2>/dev/null)
+  local TRUSTSTORE_PASSWORD=$(openssl rand -base64 32 2>/dev/null)
+  local TMP_CERT=ca-bundle-temp.crt
+  local -r CRT_DELIMITER="/-----BEGIN CERTIFICATE-----/"
+  local KUBE_SA_FOLDER="/var/run/secrets/kubernetes.io/serviceaccount"
+  local KEYSTORE_FILE="/output/resources/security/key.p12"
+  local TRUSTSTORE_FILE="/output/resources/security/trust.p12"
+
+  # Import the private key and certificate into new keytore
+  if [ -f "${CERT_FOLDER}/${KEY_FILE}" ] && [ -f "${CERT_FOLDER}/${CRT_FILE}" ]; then
+    echo "Found mounted TLS certificates, generating keystore"
+    mkdir -p /output/resources/security
+    openssl pkcs12 -export \
+      -name "defaultKeyStore" \
+      -inkey "${CERT_FOLDER}/${KEY_FILE}" \
+      -in "${CERT_FOLDER}/${CRT_FILE}" \
+      -out "${KEYSTORE_FILE}" \
+      -password pass:"${PASSWORD}" >&/dev/null
+
+     # Since we are creating new keystore, always write new password to a file
+    sed "s|REPLACE|$PASSWORD|g" $SNIPPETS_SOURCE/keystore.xml > $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+
+    # Add mounted CA to the truststore
+    if [ -f "${CERT_FOLDER}/${CA_FILE}" ]; then
+        echo "Found mounted TLS CA certificate, adding to truststore"
+        keytool -import -storetype pkcs12 -noprompt -keystore "${TRUSTSTORE_FILE}" -file "${CERT_FOLDER}/${CA_FILE}" \
+          -storepass "${TRUSTSTORE_PASSWORD}" -alias "service-ca" >&/dev/null    
+    fi
+  fi
+
+  # Add kubernetes CA certificates to the truststore
+  # CA bundles need to be split and added as individual certificates
+  if [ "$SEC_IMPORT_K8S_CERTS" = "true" ] && [ -d "${KUBE_SA_FOLDER}" ]; then
+    mkdir /tmp/certs
+    pushd /tmp/certs >&/dev/null
+    cat ${KUBE_SA_FOLDER}/*.crt >${TMP_CERT}
+    csplit -s -z -f crt- "${TMP_CERT}" "${CRT_DELIMITER}" '{*}'
+    for CERT_FILE in crt-*; do
+      keytool -import -storetype pkcs12 -noprompt -keystore "${TRUSTSTORE_FILE}" -file "${CERT_FILE}" \
+        -storepass "${TRUSTSTORE_PASSWORD}" -alias "service-sa-${CERT_FILE}" >&/dev/null
+    done
+    popd >&/dev/null
+    rm -rf /tmp/certs
+  fi
+
+  # Add the keystore password to server configuration
+  if [ ! -e $keystorePath ]; then
+    sed "s|REPLACE|$PASSWORD|g" $SNIPPETS_SOURCE/keystore.xml > $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+  fi
+  if [ -e $TRUSTSTORE_FILE ]; then
+    sed "s|PWD_TRUST|$TRUSTSTORE_PASSWORD|g" $SNIPPETS_SOURCE/truststore.xml > $SNIPPETS_TARGET_OVERRIDES/truststore.xml
+  else
+    cp $SNIPPETS_SOURCE/trustDefault.xml $SNIPPETS_TARGET_OVERRIDES/trustDefault.xml  
+  fi
+}
+
 case "${LICENSE,,}" in
   "accept" ) # Suppress license message in logs
     grep -s -F "com.ibm.ws.logging.hideMessage" /config/bootstrap.properties \
@@ -25,22 +86,7 @@ SNIPPETS_TARGET_OVERRIDES=/config/configDropins/overrides
 
 keystorePath="$SNIPPETS_TARGET_DEFAULTS/keystore.xml"
 
-if [ "$SSL" == "true" ] || [ "$TLS" == "true" ]
-then
-  cp $SNIPPETS_SOURCE/tls.xml $SNIPPETS_TARGET_OVERRIDES/tls.xml
-fi
-
-if [ "$SSL" != "false" ] && [ "$TLS" != "false" ]
-then
-  if [ ! -e $keystorePath ]
-  then
-    # Generate the keystore.xml
-    export KEYSTOREPWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
-    sed -i.bak "s|REPLACE|$KEYSTOREPWD|g" $SNIPPETS_SOURCE/keystore.xml
-    cp $SNIPPETS_SOURCE/keystore.xml $SNIPPETS_TARGET_DEFAULTS/keystore.xml
-  fi
-fi
-
+importKeyCert
 
 # Pass on to the real server run
 exec "$@"
diff --git a/websphere-liberty_kernel/Dockerfile.ubuntu.ibmjava8 b/websphere-liberty_kernel/Dockerfile.ubuntu.ibmjava8
index 74db0c7..78ac5d7 100644
--- a/websphere-liberty_kernel/Dockerfile.ubuntu.ibmjava8
+++ b/websphere-liberty_kernel/Dockerfile.ubuntu.ibmjava8
@@ -14,6 +14,9 @@
 
 FROM ibmjava:8-jre
 
+ARG VERBOSE=false
+ARG OPENJ9_SCC=true
+
 LABEL org.opencontainers.image.authors="Arthur De Magalhaes, Chris Potter" \
       org.opencontainers.image.vendor="IBM" \
       org.opencontainers.image.url="http://wasdev.net" \
@@ -52,7 +55,8 @@ LABEL "ProductID"="fbf6a96d49214c0abc6a3bc5da6e48cd" \
 
 # Set Path Shortcuts
 ENV LOG_DIR=/logs \
-    WLP_OUTPUT_DIR=/opt/ibm/wlp/output 
+    WLP_OUTPUT_DIR=/opt/ibm/wlp/output \
+    OPENJ9_SCC=$OPENJ9_SCC
 
 # Configure WebSphere Liberty
 RUN /opt/ibm/wlp/bin/server create \
@@ -93,6 +97,12 @@ RUN mkdir /logs \
     && chown -R 1001:0 /home/default \
     && chmod -R g+rw /home/default
 
+# Create a new SCC layer
+RUN if [ "$OPENJ9_SCC" = "true" ]; then populate_scc.sh; fi \
+    && rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache \
+    && chown -R 1001:0 /opt/ibm/wlp/output \
+    && chmod -R g+rwx /opt/ibm/wlp/output
+
 #These settings are needed so that we can run as a different user than 1001 after server warmup
 ENV RANDFILE=/tmp/.rnd \
     IBM_JAVA_OPTIONS="-Xshareclasses:name=liberty,nonfatal,cacheDir=/output/.classCache/ ${IBM_JAVA_OPTIONS}"
diff --git a/websphere-liberty_kernel/helpers/build/configuration_snippets/trustDefault.xml b/websphere-liberty_kernel/helpers/build/configuration_snippets/trustDefault.xml
new file mode 100644
index 0000000..f49104f
--- /dev/null
+++ b/websphere-liberty_kernel/helpers/build/configuration_snippets/trustDefault.xml
@@ -0,0 +1,4 @@
+<server description="Default Server">
+    <ssl id="defaultSSLConfig"  trustDefaultCerts="${SEC_TLS_TRUSTDEFAULTCERTS}"/>
+    <variable name="SEC_TLS_TRUSTDEFAULTCERTS" defaultValue="false"/>
+</server>
diff --git a/websphere-liberty_kernel/helpers/build/configuration_snippets/truststore.xml b/websphere-liberty_kernel/helpers/build/configuration_snippets/truststore.xml
new file mode 100644
index 0000000..980e8ea
--- /dev/null
+++ b/websphere-liberty_kernel/helpers/build/configuration_snippets/truststore.xml
@@ -0,0 +1,5 @@
+<server description="Default Server">
+    <ssl id="defaultSSLConfig" keyStoreRef="defaultKeyStore" trustStoreRef="defaultTrustStore" trustDefaultCerts="${SEC_TLS_TRUSTDEFAULTCERTS}"/>
+    <keyStore id="defaultTrustStore" location="${server.output.dir}/resources/security/trust.p12" type="PKCS12" password="PWD_TRUST" />
+    <variable name="SEC_TLS_TRUSTDEFAULTCERTS" defaultValue="false"/>
+</server>
diff --git a/websphere-liberty_kernel/helpers/build/configure.sh b/websphere-liberty_kernel/helpers/build/configure.sh
index 6579927..79b39c7 100755
--- a/websphere-liberty_kernel/helpers/build/configure.sh
+++ b/websphere-liberty_kernel/helpers/build/configure.sh
@@ -86,8 +86,8 @@ then
   then
     # Generate the keystore.xml
     export KEYSTOREPWD=$(openssl rand -base64 32)
-    sed -i.bak "s|REPLACE|$KEYSTOREPWD|g" $SNIPPETS_SOURCE/keystore.xml
-    cp $SNIPPETS_SOURCE/keystore.xml $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+    sed "s|REPLACE|$KEYSTOREPWD|g" $SNIPPETS_SOURCE/keystore.xml > $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+    chmod g+w $SNIPPETS_TARGET_DEFAULTS/keystore.xml
   fi
 fi
 
@@ -106,7 +106,10 @@ fi
 find /opt/ibm/fixes -type f -name "*.jar"  -print0 | sort -z | xargs -0 -n 1 -r -I {} java -jar {} --installLocation $WLP_INSTALL_DIR
 #Make sure that group write permissions are set correctly after installing new features
 find /opt/ibm/wlp -perm -g=w -print0 | xargs -0 -r chmod -R g+rw
-# Server start/stop to populate the /output/workarea and make subsequent server starts faster
-/opt/ibm/wlp/bin/server start && /opt/ibm/wlp/bin/server stop && rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache /output/workarea && chmod -R g+rwx /opt/ibm/wlp/output/*
+# Create a new SCC layer
+if [ "$OPENJ9_SCC" == "true" ]
+then
+  populate_scc.sh
+fi
 #Make folder executable for a group
 find /opt/ibm/wlp -type d -perm -g=x -print0 | xargs -0 -r chmod -R g+rwx
diff --git a/websphere-liberty_kernel/helpers/build/populate_scc.sh b/websphere-liberty_kernel/helpers/build/populate_scc.sh
new file mode 100755
index 0000000..1eb884d
--- /dev/null
+++ b/websphere-liberty_kernel/helpers/build/populate_scc.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+if [ "$VERBOSE" != "true" ]; then
+  exec &>/dev/null
+fi
+
+set -Eeox pipefail
+
+SCC_SIZE="80m"  # Default size of the SCC layer.
+ITERATIONS=2    # Number of iterations to run to populate it.
+TRIM_SCC=yes    # Trim the SCC to eliminate any wasted space.
+
+while getopts ":i:s:tdh" OPT
+do
+  case "$OPT" in
+    i)
+      ITERATIONS="$OPTARG"
+      ;;
+    s)
+      [ "${OPTARG: -1}" == "m" ] || ( echo "Missing m suffix." && exit 1 )
+      SCC_SIZE="$OPTARG"
+      ;;
+    t)
+      TRIM_SCC=yes
+      ;;
+    d)
+      TRIM_SCC=no
+      ;;
+    h)
+      echo \
+"Usage: $0 [-i iterations] [-s size] [-t] [-d]
+  -i <iterations> Number of iterations to run to populate the SCC. (Default: $ITERATIONS)
+  -s <size>       Size of the SCC in megabytes (m suffix required). (Default: $SCC_SIZE)
+  -t              Trim the SCC to eliminate most of the free space, if any.
+  -d              Don't trim the SCC.
+
+  Trimming enabled=$TRIM_SCC"
+      exit 1
+      ;;
+    \?)
+      echo "Unrecognized option: $OPTARG" 1>&2
+      exit 1
+      ;;
+    :)
+      echo "Missing argument for option: $OPTARG" 1>&2
+      exit 1
+      ;;
+  esac
+done
+
+# Make sure the following Java commands don't disturb our class cache until we're ready to populate it
+# by unsetting IBM_JAVA_OPTIONS if it is currently defined.
+unset IBM_JAVA_OPTIONS
+
+# Explicity create a class cache layer for this image layer here rather than allowing
+# `server start` to do it, which will lead to problems because multiple JVMs will be started.
+java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,createLayer -Xscmx$SCC_SIZE -version
+
+if [ $TRIM_SCC == yes ]
+then
+  echo "Calculating SCC layer upper bound, starting with initial size $SCC_SIZE."
+  # Populate the newly created class cache layer.
+  export IBM_JAVA_OPTIONS="-Xshareclasses:name=liberty,cacheDir=/output/.classCache/"
+  /opt/ibm/wlp/bin/server start && /opt/ibm/wlp/bin/server stop
+  # Find out how full it is.
+  unset IBM_JAVA_OPTIONS
+  FULL=`( java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,printTopLayerStats || true ) 2>&1 | awk '/^Cache is [0-9.]*% .*full/ {print substr($3, 1, length($3)-1)}'`
+  echo "SCC layer is $FULL% full. Destroying layer."
+  # Destroy the layer once we know roughly how much space we need.
+  java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,destroy || true
+  # Remove the m suffix.
+  SCC_SIZE="${SCC_SIZE:0:-1}"
+  # Calculate the new size based on how full the layer was (rounded to nearest m).
+  SCC_SIZE=`awk "BEGIN {print int($SCC_SIZE * $FULL / 100.0 + 0.5)}"`
+  # Make sure size is >0.
+  [ $SCC_SIZE -eq 0 ] && SCC_SIZE=1
+  # Add the m suffix back.
+  SCC_SIZE="${SCC_SIZE}m"
+  echo "Re-creating layer with size $SCC_SIZE."
+  # Recreate the layer with the new size.
+  java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,createLayer -Xscmx$SCC_SIZE -version
+fi
+
+# Populate the newly created class cache layer.
+export IBM_JAVA_OPTIONS="-Xshareclasses:name=liberty,cacheDir=/output/.classCache/"
+
+# Server start/stop to populate the /output/workarea and make subsequent server starts faster.
+for ((i=0; i<$ITERATIONS; i++))
+do
+  /opt/ibm/wlp/bin/server start && /opt/ibm/wlp/bin/server stop
+done
+
+rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache && chmod -R g+rwx /opt/ibm/wlp/output/*
+
+unset IBM_JAVA_OPTIONS
+# Tell the user how full the final layer is.
+FULL=`( java -Xshareclasses:name=liberty,cacheDir=/output/.classCache/,printTopLayerStats || true ) 2>&1 | awk '/^Cache is [0-9.]*% .*full/ {print substr($3, 1, length($3)-1)}'`
+echo "SCC layer is $FULL% full."
diff --git a/websphere-liberty_kernel/helpers/runtime/docker-server.sh b/websphere-liberty_kernel/helpers/runtime/docker-server.sh
index 5d196ad..e6fa5ea 100755
--- a/websphere-liberty_kernel/helpers/runtime/docker-server.sh
+++ b/websphere-liberty_kernel/helpers/runtime/docker-server.sh
@@ -1,5 +1,66 @@
 #!/bin/bash
 
+function importKeyCert() {
+  local CERT_FOLDER="${TLS_DIR:-/etc/x509/certs}"
+  local CRT_FILE="tls.crt"
+  local KEY_FILE="tls.key"
+  local CA_FILE="ca.crt"
+  local PASSWORD=$(openssl rand -base64 32 2>/dev/null)
+  local TRUSTSTORE_PASSWORD=$(openssl rand -base64 32 2>/dev/null)
+  local TMP_CERT=ca-bundle-temp.crt
+  local -r CRT_DELIMITER="/-----BEGIN CERTIFICATE-----/"
+  local KUBE_SA_FOLDER="/var/run/secrets/kubernetes.io/serviceaccount"
+  local KEYSTORE_FILE="/output/resources/security/key.p12"
+  local TRUSTSTORE_FILE="/output/resources/security/trust.p12"
+
+  # Import the private key and certificate into new keytore
+  if [ -f "${CERT_FOLDER}/${KEY_FILE}" ] && [ -f "${CERT_FOLDER}/${CRT_FILE}" ]; then
+    echo "Found mounted TLS certificates, generating keystore"
+    mkdir -p /output/resources/security
+    openssl pkcs12 -export \
+      -name "defaultKeyStore" \
+      -inkey "${CERT_FOLDER}/${KEY_FILE}" \
+      -in "${CERT_FOLDER}/${CRT_FILE}" \
+      -out "${KEYSTORE_FILE}" \
+      -password pass:"${PASSWORD}" >&/dev/null
+
+     # Since we are creating new keystore, always write new password to a file
+    sed "s|REPLACE|$PASSWORD|g" $SNIPPETS_SOURCE/keystore.xml > $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+
+    # Add mounted CA to the truststore
+    if [ -f "${CERT_FOLDER}/${CA_FILE}" ]; then
+        echo "Found mounted TLS CA certificate, adding to truststore"
+        keytool -import -storetype pkcs12 -noprompt -keystore "${TRUSTSTORE_FILE}" -file "${CERT_FOLDER}/${CA_FILE}" \
+          -storepass "${TRUSTSTORE_PASSWORD}" -alias "service-ca" >&/dev/null    
+    fi
+  fi
+
+  # Add kubernetes CA certificates to the truststore
+  # CA bundles need to be split and added as individual certificates
+  if [ "$SEC_IMPORT_K8S_CERTS" = "true" ] && [ -d "${KUBE_SA_FOLDER}" ]; then
+    mkdir /tmp/certs
+    pushd /tmp/certs >&/dev/null
+    cat ${KUBE_SA_FOLDER}/*.crt >${TMP_CERT}
+    csplit -s -z -f crt- "${TMP_CERT}" "${CRT_DELIMITER}" '{*}'
+    for CERT_FILE in crt-*; do
+      keytool -import -storetype pkcs12 -noprompt -keystore "${TRUSTSTORE_FILE}" -file "${CERT_FILE}" \
+        -storepass "${TRUSTSTORE_PASSWORD}" -alias "service-sa-${CERT_FILE}" >&/dev/null
+    done
+    popd >&/dev/null
+    rm -rf /tmp/certs
+  fi
+
+  # Add the keystore password to server configuration
+  if [ ! -e $keystorePath ]; then
+    sed "s|REPLACE|$PASSWORD|g" $SNIPPETS_SOURCE/keystore.xml > $SNIPPETS_TARGET_DEFAULTS/keystore.xml
+  fi
+  if [ -e $TRUSTSTORE_FILE ]; then
+    sed "s|PWD_TRUST|$TRUSTSTORE_PASSWORD|g" $SNIPPETS_SOURCE/truststore.xml > $SNIPPETS_TARGET_OVERRIDES/truststore.xml
+  else
+    cp $SNIPPETS_SOURCE/trustDefault.xml $SNIPPETS_TARGET_OVERRIDES/trustDefault.xml  
+  fi
+}
+
 case "${LICENSE,,}" in
   "accept" ) # Suppress license message in logs
     grep -s -F "com.ibm.ws.logging.hideMessage" /config/bootstrap.properties \
@@ -25,22 +86,7 @@ SNIPPETS_TARGET_OVERRIDES=/config/configDropins/overrides
 
 keystorePath="$SNIPPETS_TARGET_DEFAULTS/keystore.xml"
 
-if [ "$SSL" == "true" ] || [ "$TLS" == "true" ]
-then
-  cp $SNIPPETS_SOURCE/tls.xml $SNIPPETS_TARGET_OVERRIDES/tls.xml
-fi
-
-if [ "$SSL" != "false" ] && [ "$TLS" != "false" ]
-then
-  if [ ! -e $keystorePath ]
-  then
-    # Generate the keystore.xml
-    export KEYSTOREPWD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
-    sed -i.bak "s|REPLACE|$KEYSTOREPWD|g" $SNIPPETS_SOURCE/keystore.xml
-    cp $SNIPPETS_SOURCE/keystore.xml $SNIPPETS_TARGET_DEFAULTS/keystore.xml
-  fi
-fi
-
+importKeyCert
 
 # Pass on to the real server run
 exec "$@"
diff --git a/websphere-liberty_latest/Dockerfile.ubuntu.ibmjava8 b/websphere-liberty_latest/Dockerfile.ubuntu.ibmjava8
index 17c8907..643d1df 100644
--- a/websphere-liberty_latest/Dockerfile.ubuntu.ibmjava8
+++ b/websphere-liberty_latest/Dockerfile.ubuntu.ibmjava8
@@ -13,7 +13,7 @@
 # limitations under the License.
 
 FROM websphere-liberty:kernel
-
+ARG VERBOSE=false
 ARG REPOSITORIES_PROPERTIES=""
 
 RUN if [ ! -z $REPOSITORIES_PROPERTIES ]; then mkdir /opt/ibm/wlp/etc/ \
@@ -24,3 +24,9 @@ RUN if [ ! -z $REPOSITORIES_PROPERTIES ]; then mkdir /opt/ibm/wlp/etc/ \
   && chmod -R g+rwx /opt/ibm/wlp/output/*
 
 COPY --chown=1001:0 server.xml /config/
+
+# Create a new SCC layer
+RUN if [ "$OPENJ9_SCC" = "true" ]; then populate_scc.sh; fi \
+    && rm -rf /output/messaging /logs/* $WLP_OUTPUT_DIR/.classCache \
+    && chown -R 1001:0 /opt/ibm/wlp/output \
+    && chmod -R g+rwx /opt/ibm/wlp/output
\ No newline at end of file

@yosifkit
Copy link
Member

Build test of #7674; eb9f827; amd64 (websphere-liberty):

$ bashbrew build websphere-liberty:beta
Building bashbrew/cache:fb34fc91fea53427281cebc6e56d00d07343b7b827c01bc94808550c7d1ec3e5 (websphere-liberty:beta)
Tagging websphere-liberty:beta

$ test/run.sh websphere-liberty:beta
testing websphere-liberty:beta
	'utc' [1/4]...passed
	'cve-2014--shellshock' [2/4]...passed
	'no-hard-coded-passwords' [3/4]...passed
	'override-cmd' [4/4]...passed


$ bashbrew build websphere-liberty:kernel
Building bashbrew/cache:32d057962ee716c2acfa62e28bcc227eb027a294c7f4c97e07c1a9d80b9f8f11 (websphere-liberty:kernel)
Tagging websphere-liberty:kernel

$ test/run.sh websphere-liberty:kernel
testing websphere-liberty:kernel
	'utc' [1/4]...passed
	'cve-2014--shellshock' [2/4]...passed
	'no-hard-coded-passwords' [3/4]...passed
	'override-cmd' [4/4]...passed


$ bashbrew build websphere-liberty:full
Building bashbrew/cache:6b853b4f0117ed2927f6081d649235042d399b1a1e4da1a339bb0d639947116c (websphere-liberty:full)
Tagging websphere-liberty:full
Tagging websphere-liberty:latest

$ test/run.sh websphere-liberty:full
testing websphere-liberty:full
	'utc' [1/4]...passed
	'cve-2014--shellshock' [2/4]...passed
	'no-hard-coded-passwords' [3/4]...passed
	'override-cmd' [4/4]...passed


$ bashbrew build websphere-liberty:20.0.0.3-kernel-java8-ibmjava
Building bashbrew/cache:87e085aa522a3c872f02033834d61f33b4713dca54f9b9541146378afdfa94db (websphere-liberty:20.0.0.3-kernel-java8-ibmjava)
Tagging websphere-liberty:20.0.0.3-kernel-java8-ibmjava

$ test/run.sh websphere-liberty:20.0.0.3-kernel-java8-ibmjava
testing websphere-liberty:20.0.0.3-kernel-java8-ibmjava
	'utc' [1/4]...passed
	'cve-2014--shellshock' [2/4]...passed
	'no-hard-coded-passwords' [3/4]...passed
	'override-cmd' [4/4]...passed


$ bashbrew build websphere-liberty:20.0.0.3-full-java8-ibmjava
Building bashbrew/cache:aa03f7938047d9fc897a104e8f55d6190c7e03475c8a73bb27257b6220e73bae (websphere-liberty:20.0.0.3-full-java8-ibmjava)
Tagging websphere-liberty:20.0.0.3-full-java8-ibmjava

$ test/run.sh websphere-liberty:20.0.0.3-full-java8-ibmjava
testing websphere-liberty:20.0.0.3-full-java8-ibmjava
	'utc' [1/4]...passed
	'cve-2014--shellshock' [2/4]...passed
	'no-hard-coded-passwords' [3/4]...passed
	'override-cmd' [4/4]...passed


$ bashbrew build websphere-liberty:19.0.0.12-kernel-java8-ibmjava
Building bashbrew/cache:79c464c4f379da8bc781de9b551f5b3a38f129d7fb5e549057ff3e6a38ed36ea (websphere-liberty:19.0.0.12-kernel-java8-ibmjava)
Tagging websphere-liberty:19.0.0.12-kernel-java8-ibmjava

$ test/run.sh websphere-liberty:19.0.0.12-kernel-java8-ibmjava
testing websphere-liberty:19.0.0.12-kernel-java8-ibmjava
	'utc' [1/4]...passed
	'cve-2014--shellshock' [2/4]...passed
	'no-hard-coded-passwords' [3/4]...passed
	'override-cmd' [4/4]...passed


$ bashbrew build websphere-liberty:19.0.0.12-full-java8-ibmjava
Building bashbrew/cache:0fd65de64073dd1ce4c8313b9a5a874ca52b81f9149b58d1f64bc01625c6e4ac (websphere-liberty:19.0.0.12-full-java8-ibmjava)
Tagging websphere-liberty:19.0.0.12-full-java8-ibmjava

$ test/run.sh websphere-liberty:19.0.0.12-full-java8-ibmjava
testing websphere-liberty:19.0.0.12-full-java8-ibmjava
	'utc' [1/4]...passed
	'cve-2014--shellshock' [2/4]...passed
	'no-hard-coded-passwords' [3/4]...passed
	'override-cmd' [4/4]...passed

@yosifkit yosifkit merged commit be44273 into docker-library:master Mar 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants