#!/usr/bin/env bash
###################################################
# author: Sean Lyu
# modify: 2019/01/07
# function: build tomcat and java base images
# 说明:
# 此脚本会分别创建tomcat和java的Dockerfile并构建基础镜像
# tomcat基础镜像根据java的不同分为JDK和JRE版, JDK版是基于alpine基础镜像来构建, 而JRE版是基于官方tomcat来构建
# 所以Dockerfile有所不同: JDK版需要分别拷贝tomcat和java并设置相关环境变量, 而JRE版则此两步都不需要
# java基础镜像是基于alpine来构建, 只需要拷贝java,设置PATH等环境变量即可
# 此脚本使用方法:
# just build one image: build.sh tomcat:7.0.85-jdk7-alpine
# following is the way of how to build mutiple versions of images(including tomcat and java, separated by commas):
# build.sh tomcat:7.0.88-jre7-alpine,tomcat:7.0.88-jre8-alpine,tomcat:8.0.52-jre7-alpine, \
# tomcat:8.0.52-jre8-alpine,tomcat:9.0.8-jre8-alpine, tomcat:6.0.48-jdk7-alpine,tomcat:7.0.85-jdk7-alpine, \
# tomcat:7.0.85-jdk8-alpine,tomcat:8.5.28-jdk7-alpine,tomcat:8.5.28-jdk8-alpine,tomcat:9.0.5-jdk7-alpine, \
# tomcat:9.0.5-jdk8-alpine,java:7-jdk-alpine,java:8-jdk-alpine
# aliyun source
# https://mirrors.aliyun.com/alpine/v3.6/main/
# https://mirrors.aliyun.com/alpine/v3.6/community/
# ustc source
# mirrors.ustc.edu.cn
####################################################
set -e
 
log_dir="/data/logs/base_images"
[[ -d "$log_dir" ]] || mkdir $log_dir
build_date=`date +%Y-%m-%d_%H-%M-%S`
logfile=${log_dir}/${build_date}.log
 
function create_dockerfile() {
    IMAGE_NAME=$1
    DOCKER_REGISTRY="ycr.xxx.com"
    TYPE=`echo $IMAGE_NAME | awk -F':' '{print $1}'`
    VERSION=`echo $IMAGE_NAME | awk -F':' '{print $2}'`
    if [[ "X$TYPE" == "Xtomcat" ]]; then
        TOMCAT_VERSION=`echo $VERSION | awk -F'-' '{print $1}'`
        TOMCAT_MAJOR=`echo $TOMCAT_VERSION | awk -F'.' '{print $1}'`
        JAVA_VERSION=`echo $VERSION | awk -F'-' '{print $2}'`
        JAVA_TYPE=${JAVA_VERSION%%[0-9]*} # 删除字条串中以数字开始的字符及右边所有
        JAVA_MAJOR=`echo ${JAVA_VERSION: -1}`
        CATALINA_HOME=/usr/local/tomcat
        TAG_end=`echo $VERSION|cut -d "-" -f2,3`
        TAG="$TOMCAT_MAJOR-$TAG_end"
        Dockerfile="Dockerfile.tomcat$VERSION"
        WORKDIR="$CATALINA_HOME"
        # for prod
        FULL_IMAGE_NAME="$DOCKER_REGISTRY/base/tomcat:$TAG"
        # for test
        #FULL_IMAGE_NAME="tomcat:$TAG"
    elif [[ "X$TYPE" == "Xjava" ]]; then
        JAVA_VERSION=`echo $VERSION | awk -F'-' '{print $1}'`
        JAVA_TYPE=`echo $VERSION | awk -F'-' '{print $2}'`
        JAVA_MAJOR=$JAVA_VERSION
        Dockerfile="Dockerfile.java$VERSION"
        WORKDIR="/app"
        # for prod
        FULL_IMAGE_NAME="$DOCKER_REGISTRY/base/java:$VERSION"
        # for test
        #FULL_IMAGE_NAME="java:$VERSION"
    fi
 
    ######## Dockerfile Part 1 ########
    if [[ "$JAVA_TYPE" == "jdk" ]]; then
        echo "FROM alpine:latest" > ./$Dockerfile
    else
        echo "FROM $DOCKER_REGISTRY/official/tomcat/tomcat:$VERSION" > ./$Dockerfile
    fi
######## Dockerfile Part 2 ########
    cat >> ./$Dockerfile << EOF
ENV LANG=en_US.UTF-8 \\
    LANGUAGE=en_US.UTF-8 \\
    LC_CTYPE=en_US.UTF-8 \\
    LC_ALL=en_US.UTF-8 \\
    TZ="Asia/Shanghai" \\
    JAVA_MAJOR=${JAVA_MAJOR} \\
    WORKDIR=${WORKDIR} \\
    BASE_IMAGE=${IMAGE_NAME}
EOF
 
    ########JDK#########
    if [[ "$TYPE" == "tomcat" && "$JAVA_TYPE" == "jdk" ]]; then
        cat >> ./$Dockerfile << EOF
ENV JAVA_HOME="/usr/local/java" \\
    CATALINA_HOME="/usr/local/tomcat" \\
    TOMCAT_VERSION=${TOMCAT_VERSION}
EOF
        cat >> ./$Dockerfile << "EOF"
ENV JRE_HOME="${JAVA_HOME}/jre" \
    CLASSPATH="${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" \
    PATH="${PATH}:${JAVA_HOME}/bin:${CATALINA_HOME}/lib:${CATALINA_HOME}/bin"
EOF
 
     elif [[ "$TYPE" == "java" && "$JAVA_TYPE" == "jdk" ]]; then
        cat >> ./$Dockerfile << "EOF"
ENV JAVA_HOME="/usr/local/java"
EOF
        cat >> ./$Dockerfile << "EOF"
ENV JRE_HOME="${JAVA_HOME}/jre" \
    CLASSPATH="${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar" \
    PATH="${PATH}:${JAVA_HOME}/bin"
EOF
    fi
 
######## Dockerfile Part 3 ########
    cat >> ./$Dockerfile <<"EOF"
WORKDIR $WORKDIR
 
RUN set -x \
    && sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories \
    && echo 'http://mirrors.aliyun.com/alpine/edge/testing' >> /etc/apk/repositories \
    && apk update \
    && apk add --no-cache --allow-untrusted --update-cache \
               wget vim curl \
               openssh-client git perl make less \
               bash bash-doc bash-completion \
               htop iftop \
               tmux fish mdocml-apropos \
               busybox-extras \
               coreutils \
               ca-certificates \
               tzdata \
               libtool \
               gcc \
               ttf-dejavu \
               fontconfig \
               wqy-zenhei@edge wqy-zenhei \
               apk-tools \
               netcat-openbsd \
               bind-tools \
    && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && echo "Asia/Shanghai" > /etc/timezone \
    \
    && sed -i -e 's/\/bin\/ash/\/bin\/bash/' /etc/passwd \
    \
    \
    && echo '\
            PS1='\''\[\e[01;33m\][\h \u:\[\e[01;34m\]\w\[\e[01;33m\]]\[\e[00m\]\$ '\'' ; \
            eval `dircolors -b` ; \
            alias ls="ls --color=auto" ; \
            alias l="ls -lah" ; \
            alias ll="ls -lh" ; \
            alias l.="ls -d .* --color=auto" ; \
            alias mv="mv -i" ; \
            alias rm="rm -i" ; \
            export PATH='"${PATH}"' \
    ' >> /etc/profile \
    && echo '. ~/.bashrc' > /root/.bash_profile \
    && echo '. /etc/profile' > /root/.bashrc \
    && echo 'set-option -g default-shell /usr/bin/fish' > /root/.tmux.conf \
    && mkdir -p /root/.config/fish/functions \
    && echo '\
           function fish_prompt ;\
               if not set -q __fish_prompt_hostname ;\
                   set -g __fish_prompt_hostname (hostname) ;\
               end ;\
               set_color -o yellow ;\
               echo -n -s "$USER" @ "$__fish_prompt_hostname" " " ;\
               set_color -o blue ;\
               echo -n (prompt_pwd) ;\
               echo -n " # " ;\
               set_color normal ;\
           end ;\
           \
           alias l="ls -la" ;\
    ' > /root/.config/fish/functions/fish_prompt.fish \
    && ln -sf /bin/bash /bin/sh \
    \
    && echo 'hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4' >> /etc/nsswitch.conf \
    \
    \
    && mkdir -p $WORKDIR /usr/local/src/confdownload /etc/config/download/ /usr/local/pinpoint-agent \
    && BASE_URL="http://developer.xxx.com/download/base_images" \
    && curl -SL $BASE_URL/public_packages/fish_greeting.fish -o /root/.config/fish/functions/fish_greeting.fish \
    && curl -SL $BASE_URL/public_packages/dumb-init_1.2.1_amd64 -o /usr/bin/dumb-init \
    && curl -SL $BASE_URL/tomcat/packages/java_options.sh -o /usr/local/bin/java_options.sh \
    && curl -SL $BASE_URL/public_packages/entrypoint.sh -o /usr/local/bin/entrypoint.sh \
    && curl -SL $BASE_URL/public_packages/confdownload/confcenterdownload -o /usr/local/src/confdownload/confcenterdownload \
    && curl -SL $BASE_URL/tomcat/packages/glibc/sgerrand.rsa.pub -o /etc/apk/keys/sgerrand.rsa.pub \
    # && curl -SL $BASE_URL/tomcat/packages/etc/inputrc -o /etc/inputrc \
    && wget $BASE_URL/tomcat/packages/pinpoint-agent.tar.gz \
    && tar -xvf pinpoint-agent.tar.gz --strip-components=1 -C /usr/local/pinpoint-agent \
    && rm -rf pinpoint-agent.tar.gz \
    && curl -SL $BASE_URL/tomcat/packages/etc/authfile.properties -o /etc/config/download/authfile.properties \
    && curl -SL $BASE_URL/tomcat/packages/etc/yhtauthfile.properties -o /etc/config/download/yhtauthfile.properties \
    \
    \
    && ALPINE_GLIBC_BASE_DIR="$BASE_URL/tomcat/packages/glibc"  \
    && ALPINE_GLIBC_PACKAGE_VERSION="2.28-r0" \
    && ALPINE_GLIBC_BASE_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
    && ALPINE_GLIBC_BIN_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
    && ALPINE_GLIBC_I18N_PACKAGE_FILENAME="$ALPINE_GLIBC_BASE_DIR/glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
    && wget $ALPINE_GLIBC_BASE_PACKAGE_FILENAME \
    && wget $ALPINE_GLIBC_BIN_PACKAGE_FILENAME \
    && wget $ALPINE_GLIBC_I18N_PACKAGE_FILENAME \
    && apk add --no-cache \
        "glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
        "glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
        "glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" \
    \
    && rm -rf "/etc/apk/keys/sgerrand.rsa.pub" *.apk \
    && /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true \
    && echo "export LANG=$LANG" > /etc/profile.d/locale.sh \
    \
    && apk del glibc-i18n \
    \
    \
EOF
    ####for JDK####
    if [[ "$JAVA_TYPE" == "jdk" ]]; then
        cat >> ./$Dockerfile <<"EOF"
    && mkdir -p $JAVA_HOME \
    && curl -SL $BASE_URL/tomcat/jdk/jdk-$JAVA_MAJOR-linux-x64.tar.gz -o $WORKDIR/java.tar.gz \
    && tar -xvf java.tar.gz --strip-components=1 -C $JAVA_HOME/ \
    \
    && rm -rf $JAVA_HOME/*src.zip \
       $JAVA_HOME/lib/missioncontrol \
       $JAVA_HOME/lib/visualvm \
       $JAVA_HOME/lib/*javafx* \
       $JAVA_HOME/jre/lib/ext/jfxrt.jar \
       $JAVA_HOME/jre/bin/javaws \
       $JAVA_HOME/jre/lib/javaws.jar \
       $JAVA_HOME/jre/lib/desktop \
       $JAVA_HOME/jre/plugin \
       $JAVA_HOME/jre/lib/deploy* \
       $JAVA_HOME/jre/lib/*javafx* \
       $JAVA_HOME/jre/lib/*jfx* \
    \
    && rm -rf java.tar.gz* \
    && curl -SL $BASE_URL/tomcat/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/local_policy.jar -o $JAVA_HOME/jre/lib/security/local_policy.jar \
    && curl -SL $BASE_URL/tomcat/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/US_export_policy.jar -o $JAVA_HOME/jre/lib/security/US_export_policy.jar \
EOF
    elif [[ "$JAVA_TYPE" == "jre" ]]; then
        cat >> ./$Dockerfile <<"EOF"
    && curl -SL $BASE_URL/tomcat/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/local_policy.jar -o $JAVA_HOME/lib/security/local_policy.jar \
    && curl -SL $BASE_URL/tomcat/packages/UnlimitedJCEPolicyJDK${JAVA_MAJOR}/US_export_policy.jar -o $JAVA_HOME/lib/security/US_export_policy.jar \
 
EOF
    fi
    # for tomcat
    if [[ "$TYPE" == "tomcat" && "$JAVA_TYPE" == "jdk" ]]; then
        cat >> ./$Dockerfile <<"EOF"
    && curl -SL $BASE_URL/tomcat/jdk/apache-tomcat-$TOMCAT_VERSION.tar.gz -o $WORKDIR/tomcat.tar.gz \
    && tar -xvf tomcat.tar.gz --strip-components=1 \
    && rm -rf tomcat.tar.gz* bin/*.bat $CATALINA_HOME/webapps/* \
    && echo 'export PATH="$PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin"' >> /etc/profile \
EOF
    fi
    if [[ "$TYPE" == "tomcat" ]]; then
        cat >> ./$Dockerfile <<"EOF"
    && rm -rf $CATALINA_HOME/bin/*.bat $CATALINA_HOME/webapps/* \
    && sed -i '/tomcat.util.scan.StandardJarScanFilter.jarsToSkip=/a bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,bcprov-*.jar,\\' \
              $CATALINA_HOME/conf/catalina.properties \
    && sed -i -e 's/<Connector port="8080"/& URIEncoding="UTF-8"/g' \
              -e '/protocol="AJP\/1.3"/s/^/<!--/' -e '/protocol="AJP\/1.3"/s/$/-->/' \
              -e '/pattern="%/s/.*/\t\tpattern="%{x-forwarded-for}i %h %l %u %t \"%r\" %s %b %{X-traceId}i %D" \/>/' \
              -e '/<\/Host>/i \\t<Valve className="org.apache.catalina.valves.RemoteIpValve"\n\t\tremoteIpHeader="x-forwarded-for"\n\t\tproxiesHeader="x-forwarded-by"\n\t\tprotocolHeader="x-forwarded-proto"/>' \
              -e '/<\/Host>/i \\t<Resources cachingAllowed="false" cacheMaxSize="0"/>' \
                 $CATALINA_HOME/conf/server.xml \
    && ln -sf /usr/local/bin/entrypoint.sh $CATALINA_HOME/bin/entrypoint.sh \
EOF
    fi
 
    # final
    cat >> ./$Dockerfile <<"EOF"
    && ln -sf /usr/local/src/confdownload/confcenterdownload /usr/local/bin/confcenterdownload \
    && chmod +x /usr/bin/dumb-init /usr/local/bin/* \
    && /bin/rm -rf /tmp/* /var/cache/apk/* \
    && curl $BASE_URL/tomcat/packages/offline.sh -o /usr/local/bin/offline.sh \
    && chmod +x /usr/local/bin/offline.sh \
    && ln -sf /usr/local/bin/offline.sh /bin/offline.sh
EOF
 
 
    if [[ "$TYPE" == "tomcat" ]]; then
        cat >> ./$Dockerfile <<"EOF"
EXPOSE 8080
 
ENTRYPOINT ["/usr/bin/dumb-init", "--", "entrypoint.sh"]
CMD ["catalina.sh", "run"]
EOF
    # for java
    elif [[ "$TYPE" == "java" ]]; then
        cat >> ./$Dockerfile << "EOF"
ENTRYPOINT ["/usr/bin/dumb-init", "--", "entrypoint.sh"]
CMD ["bash"]
EOF
    fi
}
 
function build_image() {
    #### Build image
#    ####for JDK####
#    if [[ "$JAVA_TYPE" == "jre" ]]; then
#        echo "jdk" > .dockerignore
#    elif [[ "$TYPE" == "tomcat" ]] && [[ "$JAVA_TYPE" == "jdk" ]]; then
#        echo `ls jdk/apache-tomcat-* | grep -v $TOMCAT_VERSION` | sed 's/ /\n/g'  > .dockerignore
#        echo `ls jdk/jdk-* | grep -v ${JAVA_MAJOR}u` | sed 's/ /\n/g'  >> .dockerignore
#    elif [[ "$TYPE" == "java" ]]; then
#        echo `ls jdk/apache-tomcat-*` | sed 's/ /\n/g'  > .dockerignore
#        echo `ls jdk/jdk-* | grep -v ${JAVA_MAJOR}u` | sed 's/ /\n/g'  >> .dockerignore
#    fi
    docker build  --rm -t $FULL_IMAGE_NAME -f $Dockerfile . && docker push $FULL_IMAGE_NAME 1>/dev/null
    if [[ $? == 0 ]]; then
      echo "====> ${FULL_IMAGE_NAME} Builded and Pushed successfully.<====" | tee -a ${logfile}
    else
      echo "====> ${FULL_IMAGE_NAME} Builded Or Pushed failed!<====" | tee -a ${logfile}
      exit 1
    fi
}
 
main() {
    echo "========================== Build Info ====================================" | tee -a ${logfile}
    echo "--> $build_date Building ${FULL_IMAGE_NAME}..." | tee -a ${logfile}
    vs=`echo $IMAGE_NAME|sed 's/,/ /g'`
    for v in `echo $vs`;do
        create_dockerfile $v
        build_image
    done
    echo "==============================END=========================================" | tee -a ${logfile}
}
 
main
cat ${logfile}