diff --git a/pom.xml b/pom.xml index f13336b192a4..c1505c1d00bb 100644 --- a/pom.xml +++ b/pom.xml @@ -126,6 +126,7 @@ twitter-http-client twitter-eventlistener-plugin presto-twitter-server + presto-twitter-server-rpm diff --git a/presto-twitter-server-rpm/README.md b/presto-twitter-server-rpm/README.md new file mode 100644 index 000000000000..d0488cb59f15 --- /dev/null +++ b/presto-twitter-server-rpm/README.md @@ -0,0 +1,46 @@ +# Presto RPM + +## RPM Package Build And Usage + +You can build an RPM package for Presto server and install Presto using the RPM. Thus, the installation is easier to manage on RPM-based systems. + +The RPM builds by default in Maven, and can be found under the directory `presto-server-rpm/target/` + +The RPM has a pre-requisite of Python >= 2.4. It also needs Oracle Java 1.8 update 40 (8u40 64-bit) pre-installed. The RPM installation will fail if any of these requirements are not +satisfied. + +To install Presto using an RPM, run: + + rpm -i presto-server--1.0.x86_64.rpm + +This will install Presto in single node mode, where both coordinator and workers are co-located on localhost. This will deploy the necessary default configurations along with a service script to control the Presto server process. + +Uninstalling the RPM is like uninstalling any other RPM, just run: + + rpm -e presto + +Note: During uninstall, any Presto related files deployed will be deleted except for the Presto logs directory `/var/log/presto`. + +## Control Scripts + +The Presto RPM will also deploy service scripts to control the Presto server process. The script is configured with chkconfig, +so that the service can be started automatically on OS boot. After installing Presto from the RPM, you can run: + + service presto [start|stop|restart|status] + +## Installation directory structure + +We use the following directory structure to deploy various Presto artifacts. + +* /usr/lib/presto/lib/: Various libraries needed to run the product. Plugins go in a plugin subdirectory. +* /etc/presto: General Presto configuration files like node.properties, jvm.config, config.properties. Connector configs go in a catalog subdirectory +* /etc/presto/env.sh: Java installation path used by Presto +* /var/log/presto: Log files +* /var/lib/presto/data: Data directory +* /usr/shared/doc/presto: Docs +* /etc/rc.d/init.d/presto: Control script + +The node.properties file requires the following two additional properties since our directory structure is different from what standard Presto expects. + + catalog.config-dir=/etc/presto/catalog + plugin.dir=/usr/lib/presto/lib/plugin diff --git a/presto-twitter-server-rpm/pom.xml b/presto-twitter-server-rpm/pom.xml new file mode 100644 index 000000000000..00ed1330bac8 --- /dev/null +++ b/presto-twitter-server-rpm/pom.xml @@ -0,0 +1,191 @@ + + + 4.0.0 + + + com.facebook.presto + presto-root + 0.210-tw-0.59 + + + presto-twitter-server-rpm + presto-twitter-server-rpm + rpm + + + ${project.parent.basedir} + + true + true + true + true + + presto-twitter-server-${project.version} + + + + + com.facebook.presto + presto-twitter-server + ${project.version} + tar.gz + runtime + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + + unpack + + + false + + + com.facebook.presto + presto-twitter-server + ${project.version} + tar.gz + ${project.build.outputDirectory} + + + + + + + + + + com.teradata + redlinerpm-maven-plugin-td + 2.1.5 + true + + + false + + + + presto-twitter-server-rpm + presto-twitter-server-rpm-${project.version}.x86_64.rpm + ${project.version} + 1 + + Applications/Databases + Presto Twitter Server RPM Package. + x86_64 + src/main/rpm/preinstall + src/main/rpm/postinstall + src/main/rpm/postremove + + + + + python + [2.4,) + + + /usr/sbin/useradd + + + /usr/sbin/groupadd + + + /usr/bin/uuidgen + + + + + + /usr/lib/presto/etc + /etc/presto + + + + + + /usr/lib/presto/bin + ${server.tar.package}/bin + + 0755 + + * + + + + + /usr/lib/presto/bin + ${server.tar.package}/bin + + + */** + + + + + /etc/init.d + dist/etc/init.d + + 0755 + + * + + + + + + /usr/lib/presto/lib + ${server.tar.package}/lib + + * + + + + + /usr/lib/presto/lib/plugin + ${server.tar.package}/plugin + + */* + + + + + /etc/presto + dist/config + + * + + + + + /usr/shared/doc/presto + ${server.tar.package} + + README.txt + + + + + + /usr/lib/presto + + + /usr/lib/presto/lib + + + + + + + + + + diff --git a/presto-twitter-server-rpm/src/main/resources/dist/config/config.properties b/presto-twitter-server-rpm/src/main/resources/dist/config/config.properties new file mode 100644 index 000000000000..2b4522a3131c --- /dev/null +++ b/presto-twitter-server-rpm/src/main/resources/dist/config/config.properties @@ -0,0 +1,6 @@ +#single node install config +coordinator=true +node-scheduler.include-coordinator=true +http-server.http.port=8080 +discovery-server.enabled=true +discovery.uri=http://localhost:8080 diff --git a/presto-twitter-server-rpm/src/main/resources/dist/config/jvm.config b/presto-twitter-server-rpm/src/main/resources/dist/config/jvm.config new file mode 100644 index 000000000000..7e832707d506 --- /dev/null +++ b/presto-twitter-server-rpm/src/main/resources/dist/config/jvm.config @@ -0,0 +1,9 @@ +-server +-Xmx16G +-XX:-UseBiasedLocking +-XX:+UseG1GC +-XX:+ExplicitGCInvokesConcurrent +-XX:+HeapDumpOnOutOfMemoryError +-XX:+UseGCOverheadLimit +-XX:+ExitOnOutOfMemoryError +-XX:ReservedCodeCacheSize=512M diff --git a/presto-twitter-server-rpm/src/main/resources/dist/config/node.properties b/presto-twitter-server-rpm/src/main/resources/dist/config/node.properties new file mode 100644 index 000000000000..35b9093d7d01 --- /dev/null +++ b/presto-twitter-server-rpm/src/main/resources/dist/config/node.properties @@ -0,0 +1,7 @@ +node.environment=test +node.id=$(uuid-generated-nodeid) +node.data-dir=/var/lib/presto/data +catalog.config-dir=/etc/presto/catalog +plugin.dir=/usr/lib/presto/lib/plugin +node.server-log-file=/var/log/presto/server.log +node.launcher-log-file=/var/log/presto/launcher.log diff --git a/presto-twitter-server-rpm/src/main/resources/dist/etc/init.d/presto b/presto-twitter-server-rpm/src/main/resources/dist/etc/init.d/presto new file mode 100644 index 000000000000..4dcd311f54ca --- /dev/null +++ b/presto-twitter-server-rpm/src/main/resources/dist/etc/init.d/presto @@ -0,0 +1,87 @@ +#!/bin/bash +# +# Manages a Presto node service +# +# chkconfig: 345 85 15 +# description: Presto node +# +### BEGIN INIT INFO +# Provides: presto +# Short-Description: presto node +# Default-Start: 3 4 5 +# Default-Stop: 0 1 2 6 +# Required-Start: $syslog $remote_fs +# Required-Stop: $syslog $remote_fs +# Should-Start: +# Should-Stop: +### END INIT INFO + +SCRIPT_NAME=$0 +ACTION_NAME=$1 +SERVICE_NAME='presto' +SERVICE_USER='presto' + +# Launcher Config. +# Use data-dir from node.properties file (assumes it to be at /etc/presto). For other args use defaults from rpm install +NODE_PROPERTIES=/etc/presto/node.properties +DATA_DIR=$(grep -Po "(?<=^node.data-dir=).*" $NODE_PROPERTIES) +SERVER_LOG_FILE=$(grep -Po "(?<=^node.server-log-file=).*" $NODE_PROPERTIES) +LAUNCHER_LOG_FILE=$(grep -Po "(?<=^node.launcher-log-file=).*" $NODE_PROPERTIES) +CONFIGURATION=(--launcher-config /usr/lib/presto/bin/launcher.properties --data-dir "$DATA_DIR" --node-config "$NODE_PROPERTIES" --jvm-config /etc/presto/jvm.config --config /etc/presto/config.properties --launcher-log-file "${LAUNCHER_LOG_FILE:-/var/log/presto/launcher.log}" --server-log-file "${SERVER_LOG_FILE:-/var/log/presto/server.log}") + +source /etc/presto/env.sh + +start () { + echo "Starting ${SERVICE_NAME} " + if [ -z "$JAVA8_HOME" ] + then + echo "Warning: No value found for JAVA8_HOME. Default Java will be used." + sudo -u $SERVICE_USER /usr/lib/presto/bin/launcher start "${CONFIGURATION[@]}" + else + sudo -u $SERVICE_USER PATH=${JAVA8_HOME}/bin:$PATH /usr/lib/presto/bin/launcher start "${CONFIGURATION[@]}" + fi + return $? +} + +stop () { + echo "Stopping ${SERVICE_NAME} " + sudo -u $SERVICE_USER /usr/lib/presto/bin/launcher stop "${CONFIGURATION[@]}" + return $? +} + +status () { + echo "Getting status for ${SERVICE_NAME} " + sudo -u $SERVICE_USER /usr/lib/presto/bin/launcher status "${CONFIGURATION[@]}" + return $? +} + + +restart () { + sudo -u $SERVICE_USER /usr/lib/presto/bin/launcher restart "${CONFIGURATION[@]}" + return $? +} + +# TODO: Add kill + +usage () { + echo $"Usage: ${SCRIPT_NAME} {start|stop|restart|status}" + return 3 +} + +case "${ACTION_NAME}" in + start) + start + ;; + stop) + stop + ;; + restart) + restart + ;; + status) + status + ;; + *) + echo $"Usage: $0 {start|stop|restart|status}" + exit 3 +esac diff --git a/presto-twitter-server-rpm/src/main/rpm/postinstall b/presto-twitter-server-rpm/src/main/rpm/postinstall new file mode 100644 index 000000000000..8afe231f5131 --- /dev/null +++ b/presto-twitter-server-rpm/src/main/rpm/postinstall @@ -0,0 +1,21 @@ +# Post installation script + +# Dynamically populated directories that we expect to exist but do +# not want to remove when removing the RPM. Ideally, we would do this +# via the RPM building plugin, but adding empty directories is not +# supported. +install --directory --mode=755 /var/lib/presto +install --directory --mode=755 /var/log/presto + +# Populate node.id from uuidgen by replacing template with the node uuid +sed -i "s/\$(uuid-generated-nodeid)/$(uuidgen)/g" /etc/presto/node.properties + +# move the presto_env.sh created during pre-install to presto config location +if [ -e /tmp/presto_env.sh ] +then + mv /tmp/presto_env.sh /etc/presto/env.sh +fi + +chown -R presto:presto /var/lib/presto +chown -R presto:presto /var/log/presto +chown -R presto:presto /etc/presto diff --git a/presto-twitter-server-rpm/src/main/rpm/postremove b/presto-twitter-server-rpm/src/main/rpm/postremove new file mode 100644 index 000000000000..145581096e64 --- /dev/null +++ b/presto-twitter-server-rpm/src/main/rpm/postremove @@ -0,0 +1,13 @@ +# Post erase script + +# if this is the last version of presto-server-rpm being removed (i.e. not on upgrade) +if [ "$1" -eq 0 ] +then + # Delete the conf directory manually during uninstall. + # rpm -e wont remove it, because this directory was manually updated in postinstall + rm -rf /etc/presto + # Delete the data directory manually during uninstall. + # rpm -e wont remove it, because this directory may later contain files not + # deployed by the rpm + rm -rf /var/lib/presto +fi diff --git a/presto-twitter-server-rpm/src/main/rpm/preinstall b/presto-twitter-server-rpm/src/main/rpm/preinstall new file mode 100644 index 000000000000..f4d2e60889d6 --- /dev/null +++ b/presto-twitter-server-rpm/src/main/rpm/preinstall @@ -0,0 +1,83 @@ +# Pre installation script + +# Ensure that the proper version of Java exists on the system + +java_version() { +# The one argument is the location of java (either $JAVA_HOME or a potential +# candidate for JAVA_HOME. + JAVA="$1"/bin/java + "$JAVA" -version 2>&1 | grep "\(java\|openjdk\) version" | awk '{ print substr($3, 2, length($3)-2); }' +} + +java_vendor() { +# The one argument is the location of java (either $JAVA_HOME or a potential +# candidate for JAVA_HOME). +# Returns the java vendor name. eg: Oracle Corporation + JAVA="$1"/bin/java + "$JAVA" -XshowSettings:properties -version 2>&1 | grep "java.vendor =" | awk '{ print $3 " " $4; }' +} + +check_if_correct_java_version() { + +# If the string is empty return non-zero code. We don't want false positives if /bin/java is +# a valid java version because that will leave java8_home unset and the init.d scripts will +# use the default java version, which may not be java 8. + if [ -z $1 ] ; then + return 1 + fi + +# The one argument is the location of java (either $JAVA_HOME or a potential +# candidate for JAVA_HOME). + JAVA_VERSION=$(java_version "$1") + JAVA_VENDOR=$(java_vendor "$1") + JAVA_UPDATE=$(echo $JAVA_VERSION | cut -d'_' -f2) + if [[ ("$JAVA_VERSION" > "1.8") && ($JAVA_UPDATE -ge 151) && ("$JAVA_VENDOR" = "Oracle Corporation") ]]; then + echo "JAVA8_HOME=$1" > /tmp/presto_env.sh + return 0 + else + return 1 + fi +} + +# if Java version of $JAVA_HOME is not 1.8 update 151 (8u151) and is not Oracle Java, then try to find it again below +if ! check_if_correct_java_version "$JAVA8_HOME" && ! check_if_correct_java_version "$JAVA_HOME"; then + java_found=false + for candidate in \ + /usr/lib/jvm/jdk1.8* \ + /usr/lib/jvm/jre1.8* \ + /usr/lib/jvm/java-8-oracle* \ + /usr/java/jdk1.8* \ + /usr/java/jre1.8* \ + /usr/jdk64/jdk1.8* \ + /usr/lib/jvm/default-java \ + /usr/java/default \ + / \ + /usr ; do + if [ -e "$candidate"/bin/java ]; then + if check_if_correct_java_version "$candidate" ; then + java_found=true + break + fi + fi + done +fi + +# if no appropriate java found +if [ "$java_found" = false ]; then + cat 1>&2 < http://www.oracle.com/technetwork/java/javase/downloads < | +| | +| Presto requires Java 1.8 update 151 (8u151) | +| NOTE: This script will attempt to find Java whether you install | +| using the binary or the RPM based installer. | ++======================================================================+ +EOF + exit 1 +fi + +getent group presto >/dev/null || /usr/sbin/groupadd -r presto +getent passwd presto >/dev/null || /usr/sbin/useradd --comment "Presto" -s /sbin/nologin -g presto -r -d /var/lib/presto presto