From bbab67aca00daf1fd3bb582329203929f4588f1a Mon Sep 17 00:00:00 2001 From: stam Date: Wed, 19 May 2021 00:14:46 +0300 Subject: [PATCH] template generator by @kasthack <3 --- bin/dotnet/Epicmorg.DockerGenerator.csproj | 10 ++ bin/dotnet/Program.cs | 95 +++++++++++++++++++ bin/dotnet/data/jira/templates/7/Dockerfile | 50 ++++++++++ bin/dotnet/data/jira/templates/7/Makefile | 5 + .../data/jira/templates/7/docker-compose.yml | 9 ++ .../data/jira/templates/7/entrypoint.sh | 89 +++++++++++++++++ bin/dotnet/data/jira/templates/8/Dockerfile | 50 ++++++++++ bin/dotnet/data/jira/templates/8/Makefile | 5 + .../data/jira/templates/8/docker-compose.yml | 9 ++ .../data/jira/templates/8/entrypoint.sh | 89 +++++++++++++++++ 10 files changed, 411 insertions(+) create mode 100644 bin/dotnet/Epicmorg.DockerGenerator.csproj create mode 100644 bin/dotnet/Program.cs create mode 100644 bin/dotnet/data/jira/templates/7/Dockerfile create mode 100644 bin/dotnet/data/jira/templates/7/Makefile create mode 100644 bin/dotnet/data/jira/templates/7/docker-compose.yml create mode 100644 bin/dotnet/data/jira/templates/7/entrypoint.sh create mode 100644 bin/dotnet/data/jira/templates/8/Dockerfile create mode 100644 bin/dotnet/data/jira/templates/8/Makefile create mode 100644 bin/dotnet/data/jira/templates/8/docker-compose.yml create mode 100644 bin/dotnet/data/jira/templates/8/entrypoint.sh diff --git a/bin/dotnet/Epicmorg.DockerGenerator.csproj b/bin/dotnet/Epicmorg.DockerGenerator.csproj new file mode 100644 index 000000000..42ed1bdff --- /dev/null +++ b/bin/dotnet/Epicmorg.DockerGenerator.csproj @@ -0,0 +1,10 @@ + + + + Exe + net5.0 + + + + + diff --git a/bin/dotnet/Program.cs b/bin/dotnet/Program.cs new file mode 100644 index 000000000..db1e74e74 --- /dev/null +++ b/bin/dotnet/Program.cs @@ -0,0 +1,95 @@ +namespace Epicmorg.DockerGenerator +{ + using System; + using System.IO; + using System.Linq; + using System.Runtime.InteropServices; + using System.Text.Json; + using System.Threading.Tasks; + + class Program + { + /// + /// EpicMorg docker build script generator + /// + /// Working directory + /// Atlassian product JSON + /// Product name + /// Overwrite existing directories + /// Silently ignore versions without templates + /// + public static async Task Main(DirectoryInfo workdir, FileInfo json, string product, bool force = false, bool ignoreVersionsWithoutTemplates = false) + { + var jsonData = File.ReadAllText(json.FullName)["downloads(".Length..^1]; + var items = JsonSerializer.Deserialize(jsonData, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + foreach (var item in items.Where(a=>a.ZipUrl.ToString().EndsWith(".tar.gz"))) + { + var majorVersion = item.Version.Split(".").First(); + var templatePath = Path.Combine(workdir.FullName, product, "templates", majorVersion); + if (!Directory.Exists(templatePath)) + { + if (!ignoreVersionsWithoutTemplates) + { + Console.Error.WriteLine("Failed to find template for the major version {0}. Exiting", majorVersion); + return; + } + else + { + Console.Error.WriteLine("Failed to find template for the major version {0}. Skipping", majorVersion); + continue; + } + } + + var localPath = Path.Combine(product, majorVersion, item.Version); + var outputPath = Path.Combine(workdir.FullName, localPath); + if (Directory.Exists(outputPath)) + { + if (!force) + { + Console.Error.WriteLine("Directory '{0}' already exists, skipping", localPath); + continue; + } + else + { + Console.Error.WriteLine("Directory '{0}' already exists, overwriting", localPath); + Directory.Delete(outputPath, true); + } + } + Directory.CreateDirectory(outputPath); + CopyFilesRecursively(new DirectoryInfo(templatePath), new DirectoryInfo(outputPath)); + File.WriteAllText( + Path.Combine(outputPath, ".env"), + @$" +RELEASE={item.Version} +DOWNLOAD_URL={item.ZipUrl} +" + ); + } + + } + + private static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target) + { + foreach (DirectoryInfo dir in source.GetDirectories()) + CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name)); + foreach (FileInfo file in source.GetFiles()) + file.CopyTo(Path.Combine(target.FullName, file.Name)); + } + + public partial class ResponseItem + { + public string Description { get; set; } + public string Edition { get; set; } + public Uri ZipUrl { get; set; } + public string TarUrl { get; set; } + public string Md5 { get; set; } + public string Size { get; set; } + public string Released { get; set; } + public string Type { get; set; } + public string Platform { get; set; } + public string Version { get; set; } + public Uri ReleaseNotes { get; set; } + public Uri UpgradeNotes { get; set; } + } + } +} diff --git a/bin/dotnet/data/jira/templates/7/Dockerfile b/bin/dotnet/data/jira/templates/7/Dockerfile new file mode 100644 index 000000000..b04d36d00 --- /dev/null +++ b/bin/dotnet/data/jira/templates/7/Dockerfile @@ -0,0 +1,50 @@ +FROM epicmorg/prod:jdk8 +LABEL maintainer="Atlassian Jira Server Team; EpicMorg DevTeam, developer@epicm.org" +ARG DEBIAN_FRONTEND=noninteractive + +################################################################## +# ARGuments +################################################################## + +#configured by dockerfile / .ENV +ARG RELEASE +ARG DOWNLOAD_URL + + +################################################################## +# Setup +################################################################## +ENV RUN_USER daemon +ENV RUN_GROUP daemon + +# https://confluence.atlassian.com/display/JSERVERM/Important+directories+and+files +ENV JIRA_HOME /var/atlassian/application-data/jira +ENV JIRA_INSTALL_DIR /opt/atlassian/jira + +VOLUME ["${JIRA_HOME}"] +WORKDIR $JIRA_HOME + +# Expose HTTP port +EXPOSE 8080 + +################################################################## +# Installing +################################################################## +RUN mkdir -p ${JIRA_INSTALL_DIR} \ + && curl -L ${DOWNLOAD_URL} | tar -xz --strip-components=1 -C "$JIRA_INSTALL_DIR" \ + && chown -R ${RUN_USER}:${RUN_GROUP} ${JIRA_INSTALL_DIR}/ \ + && sed -i -e 's/^JVM_SUPPORT_RECOMMENDED_ARGS=""$/: \${JVM_SUPPORT_RECOMMENDED_ARGS:=""}/g' ${JIRA_INSTALL_DIR}/bin/setenv.sh \ + && sed -i -e 's/^JVM_\(.*\)_MEMORY="\(.*\)"$/: \${JVM_\1_MEMORY:=\2}/g' ${JIRA_INSTALL_DIR}/bin/setenv.sh \ + && sed -i -e 's/grep "java version"/grep -E "(openjdk|java) version"/g' ${JIRA_INSTALL_DIR}/bin/check-java.sh \ + && sed -i -e 's/port="8080"/port="8080" secure="${catalinaConnectorSecure}" scheme="${catalinaConnectorScheme}" proxyName="${catalinaConnectorProxyName}" proxyPort="${catalinaConnectorProxyPort}"/' ${JIRA_INSTALL_DIR}/conf/server.xml && \ + + update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \ + apt clean -y && \ + apt autoclean -y && \ + rm -rfv /var/lib/apt/lists/* && \ + rm -rfv /var/cache/apt/archives/*.deb + +CMD ["/entrypoint.sh", "-fg"] +ENTRYPOINT ["/usr/bin/tini", "--"] +COPY entrypoint.sh /entrypoint.sh +COPY . /tmp diff --git a/bin/dotnet/data/jira/templates/7/Makefile b/bin/dotnet/data/jira/templates/7/Makefile new file mode 100644 index 000000000..82c5a2de6 --- /dev/null +++ b/bin/dotnet/data/jira/templates/7/Makefile @@ -0,0 +1,5 @@ +all: app + +app: + docker-compose build --compress + docker-compose push diff --git a/bin/dotnet/data/jira/templates/7/docker-compose.yml b/bin/dotnet/data/jira/templates/7/docker-compose.yml new file mode 100644 index 000000000..4269f77ac --- /dev/null +++ b/bin/dotnet/data/jira/templates/7/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3.9' +services: + app: + image: "epicmorg/jira:${RELEASE}" + build: + context: . + args: + RELEASE: ${RELEASE} + DOWNLOAD_URL: ${DOWNLOAD_URL} \ No newline at end of file diff --git a/bin/dotnet/data/jira/templates/7/entrypoint.sh b/bin/dotnet/data/jira/templates/7/entrypoint.sh new file mode 100644 index 000000000..50ee4ecd1 --- /dev/null +++ b/bin/dotnet/data/jira/templates/7/entrypoint.sh @@ -0,0 +1,89 @@ +#!/bin/bash +set -euo pipefail + +export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::") +export JRE_HOME="$JAVA_HOME/jre" +export JAVA_BINARY="$JRE_HOME/bin/java" +export JAVA_VERSION=$("$JAVA_BINARY" -version 2>&1 | awk -F '"' '/version/ {print $2}') + +# Setup Catalina Opts +: ${CATALINA_CONNECTOR_PROXYNAME:=} +: ${CATALINA_CONNECTOR_PROXYPORT:=} +: ${CATALINA_CONNECTOR_SCHEME:=http} +: ${CATALINA_CONNECTOR_SECURE:=false} + +: ${CATALINA_OPTS:=} + +: ${JAVA_OPTS:=} + +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorProxyName=${CATALINA_CONNECTOR_PROXYNAME}" +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorProxyPort=${CATALINA_CONNECTOR_PROXYPORT}" +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorScheme=${CATALINA_CONNECTOR_SCHEME}" +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorSecure=${CATALINA_CONNECTOR_SECURE}" + +export JAVA_OPTS="${JAVA_OPTS} ${CATALINA_OPTS}" + +# Setup Data Center configuration +if [ ! -f "/etc/container_id" ]; then + uuidgen > /etc/container_id +fi +CONTAINER_ID=$(cat /etc/container_id) +CONTAINER_SHORT_ID=${CONTAINER_ID::8} + +: ${CLUSTERED:=false} +: ${JIRA_NODE_ID:=jira_node_${CONTAINER_SHORT_ID}} +: ${JIRA_SHARED_HOME:=${JIRA_HOME}/shared} +: ${EHCACHE_PEER_DISCOVERY:=} +: ${EHCACHE_LISTENER_HOSTNAME:=} +: ${EHCACHE_LISTENER_PORT:=} +: ${EHCACHE_LISTENER_SOCKETTIMEOUTMILLIS:=} +: ${EHCACHE_MULTICAST_ADDRESS:=} +: ${EHCACHE_MULTICAST_PORT:=} +: ${EHCACHE_MULTICAST_TIMETOLIVE:=} +: ${EHCACHE_MULTICAST_HOSTNAME:=} + +# Cleanly set/unset values in cluster.properties +function set_cluster_property { + if [ -z $2 ]; then + if [ -f "${JIRA_HOME}/cluster.properties" ]; then + sed -i -e "/^${1}/d" "${JIRA_HOME}/cluster.properties" + fi + return + fi + if [ ! -f "${JIRA_HOME}/cluster.properties" ]; then + echo "${1}=${2}" >> "${JIRA_HOME}/cluster.properties" + elif grep "^${1}" "${JIRA_HOME}/cluster.properties"; then + sed -i -e "s#^${1}=.*#${1}=${2}#g" "${JIRA_HOME}/cluster.properties" + else + echo "${1}=${2}" >> "${JIRA_HOME}/cluster.properties" + fi +} + +if [ "${CLUSTERED}" == "true" ]; then + set_cluster_property "jira.node.id" "${JIRA_NODE_ID}" + set_cluster_property "jira.shared.home" "${JIRA_SHARED_HOME}" + set_cluster_property "ehcache.peer.discovery" "${EHCACHE_PEER_DISCOVERY}" + set_cluster_property "ehcache.listener.hostName" "${EHCACHE_LISTENER_HOSTNAME}" + set_cluster_property "ehcache.listener.port" "${EHCACHE_LISTENER_PORT}" + set_cluster_property "ehcache.listener.socketTimeoutMillis" "${EHCACHE_LISTENER_PORT}" + set_cluster_property "ehcache.multicast.address" "${EHCACHE_MULTICAST_ADDRESS}" + set_cluster_property "ehcache.multicast.port" "${EHCACHE_MULTICAST_PORT}" + set_cluster_property "ehcache.multicast.timeToLive" "${EHCACHE_MULTICAST_TIMETOLIVE}" + set_cluster_property "ehcache.multicast.hostName" "${EHCACHE_MULTICAST_HOSTNAME}" +fi + + +# Start Jira as the correct user +if [ "${UID}" -eq 0 ]; then + echo "User is currently root. Will change directory ownership to ${RUN_USER}:${RUN_GROUP}, then downgrade permission to ${RUN_USER}" + PERMISSIONS_SIGNATURE=$(stat -c "%u:%U:%a" "${JIRA_HOME}") + EXPECTED_PERMISSIONS=$(id -u ${RUN_USER}):${RUN_USER}:700 + if [ "${PERMISSIONS_SIGNATURE}" != "${EXPECTED_PERMISSIONS}" ]; then + chmod -R 700 "${JIRA_HOME}" && + chown -R "${RUN_USER}:${RUN_GROUP}" "${JIRA_HOME}" + fi + # Now drop privileges + exec su -s /bin/bash "${RUN_USER}" -c "$JIRA_INSTALL_DIR/bin/start-jira.sh $@" +else + exec "$JIRA_INSTALL_DIR/bin/start-jira.sh" "$@" +fi diff --git a/bin/dotnet/data/jira/templates/8/Dockerfile b/bin/dotnet/data/jira/templates/8/Dockerfile new file mode 100644 index 000000000..b04d36d00 --- /dev/null +++ b/bin/dotnet/data/jira/templates/8/Dockerfile @@ -0,0 +1,50 @@ +FROM epicmorg/prod:jdk8 +LABEL maintainer="Atlassian Jira Server Team; EpicMorg DevTeam, developer@epicm.org" +ARG DEBIAN_FRONTEND=noninteractive + +################################################################## +# ARGuments +################################################################## + +#configured by dockerfile / .ENV +ARG RELEASE +ARG DOWNLOAD_URL + + +################################################################## +# Setup +################################################################## +ENV RUN_USER daemon +ENV RUN_GROUP daemon + +# https://confluence.atlassian.com/display/JSERVERM/Important+directories+and+files +ENV JIRA_HOME /var/atlassian/application-data/jira +ENV JIRA_INSTALL_DIR /opt/atlassian/jira + +VOLUME ["${JIRA_HOME}"] +WORKDIR $JIRA_HOME + +# Expose HTTP port +EXPOSE 8080 + +################################################################## +# Installing +################################################################## +RUN mkdir -p ${JIRA_INSTALL_DIR} \ + && curl -L ${DOWNLOAD_URL} | tar -xz --strip-components=1 -C "$JIRA_INSTALL_DIR" \ + && chown -R ${RUN_USER}:${RUN_GROUP} ${JIRA_INSTALL_DIR}/ \ + && sed -i -e 's/^JVM_SUPPORT_RECOMMENDED_ARGS=""$/: \${JVM_SUPPORT_RECOMMENDED_ARGS:=""}/g' ${JIRA_INSTALL_DIR}/bin/setenv.sh \ + && sed -i -e 's/^JVM_\(.*\)_MEMORY="\(.*\)"$/: \${JVM_\1_MEMORY:=\2}/g' ${JIRA_INSTALL_DIR}/bin/setenv.sh \ + && sed -i -e 's/grep "java version"/grep -E "(openjdk|java) version"/g' ${JIRA_INSTALL_DIR}/bin/check-java.sh \ + && sed -i -e 's/port="8080"/port="8080" secure="${catalinaConnectorSecure}" scheme="${catalinaConnectorScheme}" proxyName="${catalinaConnectorProxyName}" proxyPort="${catalinaConnectorProxyPort}"/' ${JIRA_INSTALL_DIR}/conf/server.xml && \ + + update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 && \ + apt clean -y && \ + apt autoclean -y && \ + rm -rfv /var/lib/apt/lists/* && \ + rm -rfv /var/cache/apt/archives/*.deb + +CMD ["/entrypoint.sh", "-fg"] +ENTRYPOINT ["/usr/bin/tini", "--"] +COPY entrypoint.sh /entrypoint.sh +COPY . /tmp diff --git a/bin/dotnet/data/jira/templates/8/Makefile b/bin/dotnet/data/jira/templates/8/Makefile new file mode 100644 index 000000000..82c5a2de6 --- /dev/null +++ b/bin/dotnet/data/jira/templates/8/Makefile @@ -0,0 +1,5 @@ +all: app + +app: + docker-compose build --compress + docker-compose push diff --git a/bin/dotnet/data/jira/templates/8/docker-compose.yml b/bin/dotnet/data/jira/templates/8/docker-compose.yml new file mode 100644 index 000000000..4269f77ac --- /dev/null +++ b/bin/dotnet/data/jira/templates/8/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3.9' +services: + app: + image: "epicmorg/jira:${RELEASE}" + build: + context: . + args: + RELEASE: ${RELEASE} + DOWNLOAD_URL: ${DOWNLOAD_URL} \ No newline at end of file diff --git a/bin/dotnet/data/jira/templates/8/entrypoint.sh b/bin/dotnet/data/jira/templates/8/entrypoint.sh new file mode 100644 index 000000000..50ee4ecd1 --- /dev/null +++ b/bin/dotnet/data/jira/templates/8/entrypoint.sh @@ -0,0 +1,89 @@ +#!/bin/bash +set -euo pipefail + +export JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::") +export JRE_HOME="$JAVA_HOME/jre" +export JAVA_BINARY="$JRE_HOME/bin/java" +export JAVA_VERSION=$("$JAVA_BINARY" -version 2>&1 | awk -F '"' '/version/ {print $2}') + +# Setup Catalina Opts +: ${CATALINA_CONNECTOR_PROXYNAME:=} +: ${CATALINA_CONNECTOR_PROXYPORT:=} +: ${CATALINA_CONNECTOR_SCHEME:=http} +: ${CATALINA_CONNECTOR_SECURE:=false} + +: ${CATALINA_OPTS:=} + +: ${JAVA_OPTS:=} + +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorProxyName=${CATALINA_CONNECTOR_PROXYNAME}" +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorProxyPort=${CATALINA_CONNECTOR_PROXYPORT}" +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorScheme=${CATALINA_CONNECTOR_SCHEME}" +CATALINA_OPTS="${CATALINA_OPTS} -DcatalinaConnectorSecure=${CATALINA_CONNECTOR_SECURE}" + +export JAVA_OPTS="${JAVA_OPTS} ${CATALINA_OPTS}" + +# Setup Data Center configuration +if [ ! -f "/etc/container_id" ]; then + uuidgen > /etc/container_id +fi +CONTAINER_ID=$(cat /etc/container_id) +CONTAINER_SHORT_ID=${CONTAINER_ID::8} + +: ${CLUSTERED:=false} +: ${JIRA_NODE_ID:=jira_node_${CONTAINER_SHORT_ID}} +: ${JIRA_SHARED_HOME:=${JIRA_HOME}/shared} +: ${EHCACHE_PEER_DISCOVERY:=} +: ${EHCACHE_LISTENER_HOSTNAME:=} +: ${EHCACHE_LISTENER_PORT:=} +: ${EHCACHE_LISTENER_SOCKETTIMEOUTMILLIS:=} +: ${EHCACHE_MULTICAST_ADDRESS:=} +: ${EHCACHE_MULTICAST_PORT:=} +: ${EHCACHE_MULTICAST_TIMETOLIVE:=} +: ${EHCACHE_MULTICAST_HOSTNAME:=} + +# Cleanly set/unset values in cluster.properties +function set_cluster_property { + if [ -z $2 ]; then + if [ -f "${JIRA_HOME}/cluster.properties" ]; then + sed -i -e "/^${1}/d" "${JIRA_HOME}/cluster.properties" + fi + return + fi + if [ ! -f "${JIRA_HOME}/cluster.properties" ]; then + echo "${1}=${2}" >> "${JIRA_HOME}/cluster.properties" + elif grep "^${1}" "${JIRA_HOME}/cluster.properties"; then + sed -i -e "s#^${1}=.*#${1}=${2}#g" "${JIRA_HOME}/cluster.properties" + else + echo "${1}=${2}" >> "${JIRA_HOME}/cluster.properties" + fi +} + +if [ "${CLUSTERED}" == "true" ]; then + set_cluster_property "jira.node.id" "${JIRA_NODE_ID}" + set_cluster_property "jira.shared.home" "${JIRA_SHARED_HOME}" + set_cluster_property "ehcache.peer.discovery" "${EHCACHE_PEER_DISCOVERY}" + set_cluster_property "ehcache.listener.hostName" "${EHCACHE_LISTENER_HOSTNAME}" + set_cluster_property "ehcache.listener.port" "${EHCACHE_LISTENER_PORT}" + set_cluster_property "ehcache.listener.socketTimeoutMillis" "${EHCACHE_LISTENER_PORT}" + set_cluster_property "ehcache.multicast.address" "${EHCACHE_MULTICAST_ADDRESS}" + set_cluster_property "ehcache.multicast.port" "${EHCACHE_MULTICAST_PORT}" + set_cluster_property "ehcache.multicast.timeToLive" "${EHCACHE_MULTICAST_TIMETOLIVE}" + set_cluster_property "ehcache.multicast.hostName" "${EHCACHE_MULTICAST_HOSTNAME}" +fi + + +# Start Jira as the correct user +if [ "${UID}" -eq 0 ]; then + echo "User is currently root. Will change directory ownership to ${RUN_USER}:${RUN_GROUP}, then downgrade permission to ${RUN_USER}" + PERMISSIONS_SIGNATURE=$(stat -c "%u:%U:%a" "${JIRA_HOME}") + EXPECTED_PERMISSIONS=$(id -u ${RUN_USER}):${RUN_USER}:700 + if [ "${PERMISSIONS_SIGNATURE}" != "${EXPECTED_PERMISSIONS}" ]; then + chmod -R 700 "${JIRA_HOME}" && + chown -R "${RUN_USER}:${RUN_GROUP}" "${JIRA_HOME}" + fi + # Now drop privileges + exec su -s /bin/bash "${RUN_USER}" -c "$JIRA_INSTALL_DIR/bin/start-jira.sh $@" +else + exec "$JIRA_INSTALL_DIR/bin/start-jira.sh" "$@" +fi