#!/bin/sh # CiAgent installation from source script (should support most Unix OSes): # download the source of the Agent, install its dependencies and set it up. # Bail on errors set -e # We shouldn't have unbounded vars set -u ####################################################################### # SCRIPT KNOBS ####################################################################### # Update for new releases, will pull this tag in the repo DEFAULT_AGENT_VERSION="4.7.3" # Pin pip version, in the past there was some buggy releases and get-pip.py # always pulls the latest version PIP_VERSION="6.1.1" VIRTUALENV_VERSION="1.11.6" SUPERVISOR_VERSION="3.3.0" SETUPTOOLS_VERSION="20.9.0" ####################################################################### # OVERRIDABLE VARIABLES: # $AGENT_VERSION # The tag or branch from which the source install performs. # Defaults to $DEFAULT_AGENT_VERSION # $CI_LICENSE_KEY # Sets your license key in the config when installing. # If not specified, the script will not install a default config. # You can find a sample at $CI_HOME/CiAgent.conf.example and create # one yourself at $CI_HOME/CiAgent.conf # $CI_HOME # Sets the agent installation directory. # Defaults to $HOME/.CiAgent # $CI_START_AGENT # 0/1 value. 1 will start the agent at the end of the script # Defaults to 1. # $EZSETUP_INSECURE # 0/1 value. 1 will install setuptools in insecure mode. # Defaults to 0. ####################################################################### set +u # accept temporarily unbound vars, because we set defaults AGENT_VERSION=${AGENT_VERSION:-$DEFAULT_AGENT_VERSION} # If CI_HOME is unset if [ -z "$CI_HOME" ]; then if [ "$(uname)" = "SunOS" ]; then CI_HOME="/opt/local/Cloudinsight" else CI_HOME=$HOME/.CiAgent fi fi CI_LICENSE_KEY=${CI_LICENSE_KEY:-no_key} CI_START_AGENT=${CI_START_AGENT:-1} EZSETUP_INSECURE=${EZSETUP_INSECURE:-0} set -u ####################################################################### # CONSTANTS ####################################################################### REPORT_FAILURE_EMAIL="support@aiops.com" AGENT_HELP_URL="http://support.aiops.com/hc/" INFRA_URL="http://ci.aiops.com/#/hosts/list" LOGFILE="$CI_HOME/CiAgent-install.log" ####################################################################### # Error reporting helpers ####################################################################### print_console() { printf "%s\n" "$*" | tee -a "$LOGFILE" >&3 } print_console_wo_nl() { printf "%s" "$*" | tee -a "$LOGFILE" >&3 } print_red() { printf "\033[31m%s\033[0m\n" "$*" | tee -a "$LOGFILE" >&3 } print_green() { printf "\033[32m%s\033[0m\n" "$*" | tee -a "$LOGFILE" >&3 } print_done() { print_green "Done" } # Will be called if an unknown error appears and that the Agent is not running # It asks the user if he wants to automatically send a failure report error_trap() { print_red "It looks like you hit an issue when trying to install the CiAgent." print_console "###" if [ -n "$ERROR_MESSAGE" ]; then print_red "$ERROR_MESSAGE" else tail -n 5 "$LOGFILE" | tee -a "$LOGFILE" >&3 fi print_console "###" print_red "Troubleshooting and basic usage information for the Agent are available at: $AGENT_HELP_URL If you're still having problems, please send an email to $REPORT_FAILURE_EMAIL with the content of $LOGFILE and any information you think would be useful and we'll try our best to help you solve your problem." exit 1 } ####################################################################### # PREPARING FOR EXECUTION ####################################################################### # We need to create this dir beforehand to put the logfile somewhere mkdir -p "$CI_HOME" # Redirect all stdout/stderr to a log file # Let fd 3 opened to output to console exec 3>&1 1>>"$LOGFILE" 2>&1 # Check logfile is writable print_console "Checking that logfile is writable" print_green "OK" # Catch errors and handle them trap error_trap INT TERM trap '[ "$?" -eq 0 ] || error_trap' EXIT ####################################################################### # CHECKING REQUIREMENTS ####################################################################### detect_python() { if command -v python2.7; then export PYTHON_CMD="python2.7" elif command -v python2; then # FreeBSD apparently uses this export PYTHON_CMD="python2" else export PYTHON_CMD="python" fi } detect_downloader() { if command -v curl; then export DOWNLOADER="curl -k -L -o" export HTTP_TESTER="curl -f" elif command -v wget; then export DOWNLOADER="wget -O" export HTTP_TESTER="wget -O /dev/null" fi } detect_sed() { if command -v sed; then export SED_CMD="sed" fi } print_console "Checking installation requirements" print_green "* uname $(uname)" # Sysstat must be installed, except on Macs ERROR_MESSAGE="sysstat is not installed on your system If you run CentOs/RHEL, you can install it by running: sudo yum install sysstat If you run Debian/Ubuntu, you can install it by running: sudo apt-get install sysstat" if [ "$(uname)" != "Darwin" ]; then iostat > /dev/null 2>&1 fi print_green "* sysstat is installed" # Detect Python version ERROR_MESSAGE="Python 2.6 or 2.7 is required to install the agent from source" detect_python if [ -z "$PYTHON_CMD" ]; then exit 1; fi $PYTHON_CMD -c "import sys; exit_code = 0 if sys.version_info[0]==2 and sys.version_info[1] > 5 else 66 ; sys.exit(exit_code)" > /dev/null 2>&1 print_green "* python found, using \`$PYTHON_CMD\`" # Detect downloader ERROR_MESSAGE="curl OR wget are required to install the agent from source" detect_downloader if [ -z "$DOWNLOADER" ]; then exit 1; fi print_green "* downloader found, using \`$DOWNLOADER\`" # sed is required to "template" the configuration files detect_sed if [ -z "$SED_CMD" ]; then print_red "* sed command not found. Will proceed without configuring the agent" else print_green "* sed found, using \`$SED_CMD\`" fi ####################################################################### # INSTALLING ####################################################################### print_console print_console print_console "Installing CiAgent $AGENT_VERSION" print_console "Installation is logged at $LOGFILE" print_console # The steps are detailed enough to know where it fails ERROR_MESSAGE="" print_console "* Setting up a python virtual env" $DOWNLOADER "$CI_HOME/virtualenv.py" "https://raw.githubusercontent.com/pypa/virtualenv/$VIRTUALENV_VERSION/virtualenv.py" $PYTHON_CMD "$CI_HOME/virtualenv.py" --no-pip --no-setuptools "$CI_HOME/venv" rm -f "$CI_HOME/virtualenv.py" rm -f "$CI_HOME/virtualenv.pyc" print_done print_console "* Activating the virtual env" # venv activation script doesn't handle -u mode set +u . "$CI_HOME/venv/bin/activate" set -u print_done VENV_PYTHON_CMD="$CI_HOME/venv/bin/python" VENV_PIP_CMD="$CI_HOME/venv/bin/pip" print_console "* Setting up setuptools" $DOWNLOADER "$CI_HOME/ez_setup.py" https://bootstrap.pypa.io/ez_setup.py if [ "$EZSETUP_INSECURE" = "0" ]; then $VENV_PYTHON_CMD "$CI_HOME/ez_setup.py" --version="$SETUPTOOLS_VERSION" --to-dir=$CI_HOME else $VENV_PYTHON_CMD "$CI_HOME/ez_setup.py" --version="$SETUPTOOLS_VERSION" --to-dir=$CI_HOME --insecure fi rm -f "$CI_HOME/setuptools-$SETUPTOOLS_VERSION.zip" rm -f "$CI_HOME/ez_setup.py" rm -f "$CI_HOME/ez_setup.pyc" print_done print_console "* Setting up pip" $DOWNLOADER "$CI_HOME/get-pip.py" https://bootstrap.pypa.io/get-pip.py $VENV_PYTHON_CMD "$CI_HOME/get-pip.py" $VENV_PIP_CMD install "pip==$PIP_VERSION" rm -f "$CI_HOME/get-pip.py" rm -f "$CI_HOME/get-pip.pyc" print_done print_console "* Downloading agent version $AGENT_VERSION" mkdir -p "$CI_HOME/agent" $DOWNLOADER "$CI_HOME/agent.tar.gz" "http://download.aiops.com/ci_agent/CiAgent-${AGENT_VERSION}-tarball.tar.gz" print_done print_console "* Uncompressing tarball" tar -xzf "$CI_HOME/agent.tar.gz" -C "$CI_HOME/agent" rm -f "$CI_HOME/agent.tar.gz" print_done print_console "* Installing requirements" $VENV_PIP_CMD install -r "$CI_HOME/agent/requirements.txt" rm -f "$CI_HOME/agent/requirements.txt" print_done print_console "* Trying to install optional requirements" "$CI_HOME/agent/pip-allow-failures.sh" "$CI_HOME/agent/requirements-opt.txt" rm -f "$CI_HOME/agent/requirements-opt.txt" print_done print_console "* Setting up a CiAgent.conf generic configuration file" if [ -z "$SED_CMD" ]; then print_console " No sed command. Proceeding without installing CiAgent.conf Please make sure that the agent's log files are explicitly configured in CiAgent.conf" else ci_conf_file="$CI_HOME/agent/CiAgent.conf" if [ "$CI_LICENSE_KEY" = "no_key" ]; then print_console " Got no license key through $CI_LICENSE_KEY. Proceeding without installing CiAgent.conf" else # Replace license key $SED_CMD -e "s/license_key:.*/license_key: $CI_LICENSE_KEY/" "$ci_conf_file.example" > "$ci_conf_file" # Disable syslog by default on SunOS as it causes errors if [ "$(uname)" = "SunOS" ]; then $SED_CMD -i -e "s/# log_to_syslog: yes/log_to_syslog: no/" "$ci_conf_file" fi chmod 640 "$ci_conf_file" fi # Setting up logging # Make the changes to the example config file if CiAgent.conf doesn't exist. if [ ! -f "$ci_conf_file" ]; then ci_conf_file="$ci_conf_file.example" fi # Remove `disable_file_logging` that was set by this script before 5.7.0 $SED_CMD -i -e "s/disable_file_logging: True/# disable_file_logging: True/" "$ci_conf_file" # Log to $CI_HOME/logs/ # Needed to avoid "unknown var $prog_log_file" log_suffix="_log_file" for prog in collector forwarder statsd jmxfetch; do if ! grep "^[[:space:]]*$prog$log_suffix" "$ci_conf_file"; then echo "$prog$log_suffix: $CI_HOME/logs/$prog.log" >> "$ci_conf_file" fi done fi print_done print_console "* Setting up init scripts" mkdir -p "$CI_HOME/bin" cp "$CI_HOME/agent/packaging/source/agent" "$CI_HOME/bin/agent" chmod +x "$CI_HOME/bin/agent" if [ "$(uname -v | awk -F'_' '{print $1}')" = "joyent" ]; then cp "$CI_HOME/agent/packaging/smartos/ci-agent" "$CI_HOME/bin/ci-agent" chmod +x "$CI_HOME/bin/ci-agent" fi print_done print_console "* Setting up supervisord" mkdir -p "$CI_HOME/logs" $VENV_PIP_CMD install "supervisor==$SUPERVISOR_VERSION" cp "$CI_HOME/agent/packaging/source/supervisord.conf" "$CI_HOME/agent/supervisord.conf" mkdir -p "$CI_HOME/run" print_done print_console "* Starting the agent" if [ "$CI_START_AGENT" = "0" ]; then print_console " Skipping due to \$CI_START_AGENT" exit 0 fi # on SmartOS, skip the test, svcadm the Agent if [ "$(uname -v | awk -F'_' '{print $1}')" = "joyent" ]; then # Install pyexpat for our version of python, a dependency for xml parsing (varnish et al.) # Tested with /bin/sh $PYTHON_CMD -V 2>&1 | awk '{split($2, arr, "."); printf("py%d%d-expat", arr[1], arr[2]);}' | xargs pkgin -y in # SMF work now svccfg import "$CI_HOME/agent/packaging/smartos/ci-agent.xml" svcadm enable site/Cloudinsight if svcs Cloudinsight; then print_done print_console "*** The Agent is running. My work here is done... (^_^) ***" exit 0 else exit $? fi fi # supervisord.conf uses relative paths so need to chdir cd "$CI_HOME" supervisord -c agent/supervisord.conf & cd - AGENT_PID=$! sleep 1 # Checking that the agent is up if ! kill -0 $AGENT_PID; then ERROR_MESSAGE="Failure when launching supervisord" exit 1 fi print_green " - supervisord started" # On errors and exit, quit properly trap '{ kill $AGENT_PID; exit 255; }' INT TERM trap '{ kill $AGENT_PID; exit; }' EXIT print_console print_green "Your Agent has started up for the first time. We're currently verifying that data is being submitted. You should see your Agent show up in Cloudinsight shortly at: $INFRA_URL" print_console print_console "* Waiting 30s to see if the Agent submits metrics correctly" c=0 while [ "$c" -lt "30" ]; do sleep 1 print_console_wo_nl "." c=$((c+1)) done # Hit this endpoint to check if the Agent is submitting metrics # and retry every sec for 60 more sec before failing print_console print_console "* Testing if the Agent is submitting metrics" ERROR_MESSAGE="The Agent hasn't submitted metrics after 90 seconds" while [ "$c" -lt "90" ]; do sleep 1 print_console_wo_nl "." if $HTTP_TESTER "http://localhost:50010/status?threshold=0"; then break fi c=$((c+1)) done print_console if [ "$c" -ge "90" ]; then error_trap fi # Yay IT WORKED! print_green "Success! Your Agent is functioning properly, and will continue to run in the foreground. To stop it, simply press CTRL-C. To start it back up again in the foreground, run the following command: $CI_HOME/bin/agent start " wait $AGENT_PID