#!/usr/bin/env bash # vim:ts=4:sts=4:sw=4:et # # Author: Hari Sekhon # Date: 2020-08-05 19:49:48 +0100 (Wed, 05 Aug 2020) # # https://github.com/harisekhon/bash-tools # # License: see accompanying Hari Sekhon LICENSE file # # If you're using my code you're welcome to connect with me on LinkedIn and optionally send me feedback to help steer this or other code I publish # # https://www.linkedin.com/in/harisekhon # # https://hub.docker.com/_/mysql set -euo pipefail [ -n "${DEBUG:-}" ] && set -x srcdir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck disable=SC1090 . "$srcdir/lib/utils.sh" # shellcheck disable=SC1090 . "$srcdir/lib/dbshell.sh" # defined in lib/dbshell.sh # shellcheck disable=SC2154 shell_description="$sql_mount_description Source a sql script: source mysql_info.sql Get shell access: \\! bash List available SQL scripts: \\! ls -l " # shellcheck disable=SC2034,SC2154 usage_description=" Boots a quick MySQL docker container and drops you in to the 'mysql' shell Multiple invocations of this script will connect to the same MySQL container if already running and the last invocation of this script to exit from the mysql shell will delete that container MySQL version can be specified using the first argument, or the \$MYSQL_VERSION environment variable, otherwise 'latest' is used Versions to use can be found from the following URL: https://hub.docker.com/_/mysql?tab=tags or programmatically on the command line (see DevOps Python tools repo): dockerhub_show_tags.py mysql Options to the 'mysql' shell command can be given using the \$MYSQL_OPTS environment variable Automatically creates shared bind mount points from host to container for convenience: $shell_description " # used by usage() in lib/utils.sh # shellcheck disable=SC2034 usage_args="[] [options] -n --name NAME Docker container name to use (default: mysql) -p --port PORT Expose MySQL port 3306 on given port number -d --no-delete Don't delete the container upon the last mysql session closing (\$DOCKER_NO_DELETE) -r --restart Force a restart of a clean MySQL instance (\$MYSQL_RESTART) -s --sample Load sample Chinook database (\$LOAD_SAMPLE)" help_usage "$@" docker_image=mysql port="" docker_opts="" password="${MYSQL_ROOT_PASSWORD:-${MYSQL_PWD:-${MYSQL_PASSWORD:-${PASSWORD:-test}}}}" while [ $# -gt 0 ]; do # DOCKER_NO_DELETE used by functions from lib # shellcheck disable=SC2034 case "$1" in -n| --name) container_name="$2" shift ;; -p| --port) port="$2" [[ "$port" =~ ^[[:digit:]]*$ ]] || die "invalid --port '$port' given" shift ;; -s|--sample) LOAD_SAMPLE_DB=1 ;; -r|--restart) MYSQL_RESTART=1 ;; -d|--no-delete) DOCKER_NO_DELETE=1 ;; *) version="$1" ;; esac shift done container_name="${container_name:-${MYSQL_CONTAINER_NAME:-mysql}}" version="${version:-${MYSQL_VERSION:-latest}}" if [ -n "$port" ]; then docker_opts="-p $port:5432" fi db="$srcdir/chinook.mysql" if [ -n "${LOAD_SAMPLE_DB:-}" ] && ! [ -f "$db" ]; then timestamp "downloading sample 'chinook' database" wget -qcO "$db" 'https://github.com/lerocha/chinook-database/blob/master/ChinookDatabase/DataSources/Chinook_MySql.sql?raw=true' #iconv -f ISO-8859-1 -t UTF-8 "$db" > "$db.utf8" fi # ensures version is correct before we kill any existing test env to switch versions timestamp "docker pull $docker_image:$version" docker_pull "$docker_image:$version" # kill existing if we have specified a different version than is running docker_ps_image_version="$(docker ps --filter "name=$container_name" --format '{{.Image}}')" if [ -n "$docker_ps_image_version" ] && [ "$docker_ps_image_version" != "$docker_image:$version" ]; then MYSQL_RESTART=1 fi # remove existing non-running container so we can boot a new one if docker_ps_not_running "name=$container_name"; then MYSQL_RESTART=1 fi if [ -n "${MYSQL_RESTART:-}" ]; then timestamp "killing existing MySQL container:" docker rm -f "$container_name" 2>/dev/null || : fi if ! docker ps -qf name="$container_name" | grep -q .; then timestamp "booting MySQL container from image '$docker_image:$version':" # defined in lib/dbshell.sh # shellcheck disable=SC2154 eval docker run -d \ --name '"$container_name"' \ "$docker_opts" \ -e MYSQL_ROOT_PASSWORD='"$password"' \ "$docker_sql_mount_switches" \ "$docker_image":"$version" #-v "$srcdir/setup/mysql/conf.d/my.cnf:/etc/mysql/conf.d/" \ wait_for_mysql_ready "$container_name" echo fi # yes expand now # shellcheck disable=SC2064 trap "echo ERROR; echo; echo; [ -z '${DEBUG:-}' ] || docker logs '$container_name'" EXIT if [ -n "${LOAD_SAMPLE_DB:-}" ]; then dbname="${db##*/}" dbname="${dbname%%.*}" timestamp "loading $dbname database" #eval docker exec -i "$container_name" mysql -u root -p"$password" "${MYSQL_OPTS:-}" -e "CREATE DATABASE IF NOT EXISTS $dbname" timestamp "loading data (this may take a minute)" # shellcheck disable=SC2086 docker exec -i -e MYSQL_PWD="$password" "$container_name" mysql -u root ${MYSQL_OPTS:-} < "${db}" timestamp "done" echo >&2 fi if has_terminal && [ -z "${DOCKER_NO_TERMINAL:-}" ]; then cat <