diff --git a/get-pmm.sh b/get-pmm.sh new file mode 100755 index 0000000000..1535d66ea9 --- /dev/null +++ b/get-pmm.sh @@ -0,0 +1,257 @@ +#!/usr/bin/env bash +# +# ############################### +# Script to run PMM 2. +# If docker is not installed, this script will try to install it as root user. +# +# Usage example: +# curl -fsSL https://raw.githubusercontent.com/percona/pmm/PMM-2.0/get-pmm.sh -o get-pmm2.sh; chmod +x get-pmm2.sh; ./get-pmm2.sh +# +################################# + +set -Eeuo pipefail +trap cleanup SIGINT SIGTERM ERR EXIT + +# Set defaults. +tag=${PMM_TAG:-"latest"} +repo=${PMM_REPO:-"percona/pmm-server"} +port=${PMM_PORT:-443} +container_name=${CONTAINER_NAME:-"pmm-server"} +interactive=0 +root_is_needed='no' + +####################################### +# Show script usage info. +####################################### +usage() { + cat <&2 -e "${1-}" +} + +####################################### +# Prints message and exit with code. +# Arguments: +# message string; +# exit code. +# Outputs: +# writes message to stderr. +####################################### +die() { + local msg=$1 + local code=${2-1} # default exit status 1 + msg "$msg" + exit "$code" +} + +####################################### +# Accept and parse script's params. +####################################### +parse_params() { + while :; do + case "${1-}" in + -h | --help) usage ;; + -v | --verbose) set -x ;; + --no-color) NO_COLOR=1 ;; + -i | --interactive) interactive=1 ;; + -t | --tag) + tag="${2-}" + shift + ;; + -r | --repo) + repo="${2-}" + shift + ;; + -p | --port) + port="${2-}" + shift + ;; + -?*) die "Unknown option: $1" ;; + *) break ;; + esac + shift + done + + args=("$@") + + return 0 +} + +####################################### +# Gathers PMM setup param in interactive mode. +####################################### +gather_info() { + msg "${GREEN}PMM Server Wizard Install${NOFORMAT}" + read -p " Port Number to start PMM Server on (default: 443): " port + read -p " PMM Server Container Name (default: pmm-server): " container_name + read -p " Override specific version (container tag) (default: latest in 2.x series) format: 2.x.y: " tag +} + +check_command() { + command -v "$@" 1>/dev/null +} + +####################################### +# Runs command as root. +####################################### +run_root() { + sh='sh -c' + if [ "$(id -un)" != 'root' ]; then + if check_command sudo; then + sh='sudo -E sh -c' + elif check_command su; then + sh='su -c' + else + die "${RED}ERROR: root rights needed to run "$*" command${NOFORMAT}" + fi + fi + ${sh} "$@" +} + +####################################### +# Installs docker if needed. +####################################### +install_docker() { + printf "Checking docker installation" + if ! check_command docker; then + printf " - not installed. Installing...\n\n" + curl -fsSL get.docker.com -o /tmp/get-docker.sh || + wget -qO /tmp/get-docker.sh get.docker.com + sh /tmp/get-docker.sh + run_root 'service docker start' || : + else + printf " - installed.\n\n" + fi + + if ! docker ps 1>/dev/null; then + root_is_needed='yes' + if ! run_root 'docker ps > /dev/null'; then + die "${RED}ERROR: cannot run "docker ps" command${NOFORMAT}" + fi + fi +} + +####################################### +# Runs docker command as root if required. +####################################### +run_docker() { + if [ "${root_is_needed}" = 'yes' ]; then + run_root "docker $*" + else + sh -c "docker $*" + fi +} + +####################################### +# Starts PMM server container with give repo, tag, name and port. +# If any PMM server instance is run - stop and backup it. +####################################### +start_pmm() { + msg "Starting PMM server..." + run_docker "pull $repo:$tag 1> /dev/null" + + if ! run_docker "inspect pmm-data 1> /dev/null 2> /dev/null"; then + run_docker "create -v /srv/ --name pmm-data percona/pmm-server:$tag /bin/true 1> /dev/null" + msg "Created PMM Data Volume: pmm-data" + fi + + if run_docker "inspect pmm-server 1> /dev/null 2> /dev/null"; then + pmm_archive="pmm-server-$(date "+%F-%H%M%S")" + msg "\tExisting PMM Server found, renaming to $pmm_archive\n" + run_docker 'stop pmm-server' || : + run_docker "rename pmm-server $pmm_archive\n" + fi + run_pmm="run -d -p $port:443 --volumes-from pmm-data --name $container_name --restart always $repo:$tag" + + run_docker "$run_pmm 1> /dev/null" + msg "Created PMM Server: $container_name" + msg "\tUse the following command if you ever need to update your container by hand:" + msg "\tdocker $run_pmm \n" +} + +####################################### +# Shows final message. +# Shows a list of addresses on which PMM server available. +####################################### +show_message() { + msg "PMM Server has been successfully setup on this system!\n" + + if check_command ifconfig; then + ips=$(ifconfig | awk '/inet / {print $2}' | sed 's/addr://') + elif check_command ip; then + ips=$(ip -f inet a | awk -F"[/ ]+" '/inet / {print $3}') + else + die "${RED}ERROR: cannot detect PMM server address${NOFORMAT}" + fi + + msg "You can access your new server using the one of following web addresses:" + for ip in $ips; do + msg "\t${BLUE}https://$ip:$port/${NOFORMAT}" + done + msg "\nThe default username is '${PURPLE}admin${NOFORMAT}' and the password is '${PURPLE}admin${NOFORMAT}' :)" + msg "Note: Some browsers may not trust the default SSL certificate when you first open one of the urls above." + msg "If this is the case, Chrome users may want to type '${PURPLE}thisisunsafe${NOFORMAT}' to bypass the warning.\n" +} + +main() { + setup_colors + if [[ $interactive == 1 ]]; then + gather_info + fi + msg "Gathering/downloading required components, this may take a moment\n" + install_docker + start_pmm + show_message +} + +parse_params "$@" + +main +die "Enjoy Percona Monitoring and Management!" 0