#!/bin/bash # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # # This installs the minimal dependencies needed for Impala # services to run. It currently handles Ubuntu and Redhat # distributions. This takes an optional argument "--install-debug-tools" # which installs extra debugging tools like curl, ping, etc. set -euo pipefail # Default level of extra debugging tools, controlled by the --install-debug-tools flag. INSTALL_DEBUG_TOOLS=none JAVA_VERSION=8 DRY_RUN=false PKG_LIST="" NON_PKG_NAMES=(apt-get yum apk install update add) function print_usage { echo "install_os_packages.sh - Helper script to install OS dependencies" echo "[--install-debug-tools ] : set the level of debug tools"\ "to install" echo "[--java ] : Use specified Java version rather than the default Java 8." echo "[--dry-run] : Print the list of packages to install." } # Wraps the passed in command to either execute it (DRY_RUN=false) or just use it # to update PKG_LIST. function wrap { if $DRY_RUN; then for arg in $@; do if [[ "${NON_PKG_NAMES[@]}" =~ "$arg" ]]; then continue elif [[ "$arg" == "-"* ]]; then # Ignores command options continue elif [[ "$PKG_LIST" != "" ]]; then PKG_LIST="$PKG_LIST,$arg" else PKG_LIST="$arg" fi done else "$@" fi } while [ -n "$*" ] do case "$1" in --install-debug-tools) INSTALL_DEBUG_TOOLS="${2-}" shift; ;; --java) JAVA_VERSION="${2-}" shift; ;; --dry-run) DRY_RUN=true ;; --help|*) print_usage exit 1 ;; esac shift done echo "INSTALL_DEBUG_TOOLS=${INSTALL_DEBUG_TOOLS}" echo "JAVA_VERSION=${JAVA_VERSION}" echo "DRY_RUN=${DRY_RUN}" case "$INSTALL_DEBUG_TOOLS" in none | basic | full) # These are valid. ;; "" | *) # The argument to --install-debug-tools is either missing, or is not a recognized # value. print_usage exit 1 ;; esac # This can get more detailed if there are specific steps # for specific versions, but at the moment the distribution # is all we need. DISTRIBUTION=Unknown if [[ -f /etc/redhat-release ]]; then echo "Identified Redhat system." DISTRIBUTION=Redhat elif [[ -f /etc/lsb-release ]]; then source /etc/lsb-release if [[ $DISTRIB_ID == Ubuntu ]]; then echo "Identified Ubuntu system." DISTRIBUTION=Ubuntu # Ubuntu 16.04 does not have Java 11 in its package repository, # so exit with an error. if [[ $DISTRIB_RELEASE == 16.04 ]] && [[ $JAVA_VERSION == 11 ]] ; then echo "ERROR: Java 11 is not supported on Ubuntu 16.04" exit 1 fi fi # Check /etc/os-release last: it exists on Red Hat and Ubuntu systems as well elif [[ -f /etc/os-release ]]; then source /etc/os-release if [[ $ID == wolfi || $ID == chainguard ]]; then echo "Identified Wolfi-based system." DISTRIBUTION=Chainguard fi fi if [[ $DISTRIBUTION == Unknown ]]; then echo "ERROR: Did not detect supported distribution." echo "Only Ubuntu, Red Hat (or related), or Wolfi base images are supported." exit 1 fi # Install minimal set of files. # Optionally install extra debug tools. if [[ $DISTRIBUTION == Ubuntu ]]; then export DEBIAN_FRONTEND=noninteractive wrap apt-get update wrap apt-get install -y \ hostname \ krb5-user \ language-pack-en \ libsasl2-2 \ libsasl2-modules \ libsasl2-modules-gssapi-mit \ openjdk-${JAVA_VERSION}-jre-headless \ tzdata # On Ubuntu there are no extra tools installed for $INSTALL_DEBUG_TOOLS == basic if [[ $INSTALL_DEBUG_TOOLS == full ]]; then echo "Installing full debug tools" wrap apt-get install -y \ curl \ dnsutils \ iproute2 \ iputils-ping \ less \ netcat-openbsd \ sudo \ vim fi elif [[ $DISTRIBUTION == Redhat ]]; then if [[ $JAVA_VERSION == 8 ]]; then JAVA_VERSION=1.8.0 fi wrap yum install -y --disableplugin=subscription-manager \ cyrus-sasl-gssapi \ cyrus-sasl-plain \ hostname \ java-${JAVA_VERSION}-openjdk-headless \ krb5-workstation \ openldap-devel \ procps-ng \ tzdata # UTF-8 masking functions require the presence of en_US.utf8. # Install the appropriate language packs. Redhat/Centos 7 come # with en_US.utf8, so there is no need to install anything. if ! grep 'release 7\.' /etc/redhat-release; then wrap yum install -y --disableplugin=subscription-manager \ glibc-langpack-en \ langpacks-en fi if [[ $INSTALL_DEBUG_TOOLS == basic || $INSTALL_DEBUG_TOOLS == full ]]; then echo "Installing basic debug tools" wrap yum install -y --disableplugin=subscription-manager \ java-${JAVA_VERSION}-openjdk-devel \ gdb fi if [[ $INSTALL_DEBUG_TOOLS == full ]]; then echo "Installing full debug tools" # Redhat 8 and 9 come with curl-minimal preinstalled, which conflicts with the # full curl package. Add --allowerasing to the yum command to allow package # replacement. wrap yum install -y --disableplugin=subscription-manager --allowerasing \ bind-utils \ curl \ iproute \ iputils \ less \ nmap-ncat \ sudo \ vim \ which fi elif [[ $DISTRIBUTION == Chainguard ]]; then # Package inventory: # glibc-locale-en and posix-libc-utils: for locale and 'locale' tool support # shadow: for groupadd and friends wrap apk add --no-cache --no-interactive \ glibc-locale-posix \ glibc-locale-en \ glibc-iconv \ posix-libc-utils \ localedef \ cyrus-sasl \ krb5-libs \ krb5 \ openssl \ openldap-dev \ openjdk-${JAVA_VERSION}-jre \ openjdk-${JAVA_VERSION}-default-jvm \ shadow \ tzdata # Set up /etc/localtime so that the container has a default local timezone. # Make this UTC. ln -sf /usr/share/zoneinfo/UTC /etc/localtime if [[ $INSTALL_DEBUG_TOOLS == basic || $INSTALL_DEBUG_TOOLS == full ]]; then echo "Installing basic debug tools" wrap apk add --no-cache --no-interactive \ gdb \ openjdk-${JAVA_VERSION}-default-jdk fi if [[ $INSTALL_DEBUG_TOOLS == full ]]; then echo "Installing full debug tools" wrap apk add --no-cache --no-interactive \ bind-tools \ curl \ iproute2 \ iputils \ less \ nmap \ sudo \ tzutils \ vim fi fi if $DRY_RUN; then echo "The following packages would be installed:" echo "$PKG_LIST" exit 0 fi # Verify en_US.utf8 is present if ! locale -a | grep en_US.utf8 ; then echo "ERROR: en_US.utf8 locale is not present." exit 1 fi if ! hostname ; then echo "ERROR: 'hostname' command failed." exit 1 fi # graceful_shutdown_backends.sh requires the pgrep utility. Verify it is present. if ! command -v pgrep ; then echo "ERROR: 'pgrep' is not present." exit 1 fi # Java must be accessible for both the frontend and the backend. Verify it is present. if ! command -v java; then echo "ERROR: Java cannot be found." exit 1 fi # Impala will fail to start if the permissions on /var/tmp are not set to include # the sticky bit (i.e. +t). Some versions of Redhat UBI images do not have # this set by default, so specifically set the sticky bit for both /tmp and /var/tmp. mkdir -p /var/tmp chmod a=rwxt /var/tmp /tmp # The busybox implementation of chmod is known to ignore certain chmod syntax variations, # so check if the directories actually have the correct permissions check_dir_stat() { target_dir=$1 stat_expect=$2 stat=$(stat -c '%u %g %a' $target_dir) if [[ "$stat" != "$stat_expect" ]]; then echo "Expect $target_dir permission '$stat_expect' but got '$stat' instead." exit 1 fi } check_dir_stat "/tmp" "0 0 1777" check_dir_stat "/var/tmp" "0 0 1777" # To minimize the size for the Docker image, clean up any unnecessary files. if [[ $DISTRIBUTION == Ubuntu ]]; then apt-get clean rm -rf /var/lib/apt/lists/* elif [[ $DISTRIBUTION == Redhat ]]; then yum clean all rm -rf /var/cache/yum/* elif [[ $DISTRIBUTION == Chainguard ]]; then rm -rf /var/cache/apk/* fi