363 lines
9.9 KiB
Bash
363 lines
9.9 KiB
Bash
#!/bin/bash
|
|
# General lib for devops scripts
|
|
# @author Craig McDaniel
|
|
#
|
|
|
|
# Source config data
|
|
source ${INCLUDE_DIR}/config.sh
|
|
|
|
# Save all arguments to the script here.
|
|
BASH_ARGS=$@
|
|
|
|
# Ensure dir exists
|
|
mkdir -p /opt/busnet/data
|
|
|
|
|
|
# Make sure there is an ssh key pair for the current user. This will be distributed to servers and
|
|
# used for Ansible SSH connections. It's not fancy at all. This is a simple solution for the BusNet
|
|
# system.
|
|
generate_busnet_key()
|
|
{
|
|
local KEY_PATH="${HOME}/.ssh/${CONFIG_ANSIBLE_KEY_NAME}"
|
|
# Only run if the key isn't there.
|
|
if [[ ! -f "$KEY_PATH" ]]; then
|
|
echo "No SSH private key detected for ansible-busnet. Generating one. DO NOT REMOVE THIS!"
|
|
ssh-keygen -t ed25519 -f "${KEY_PATH}" -N "" -C "ansible-busnet@$(hostname)"
|
|
fi
|
|
}
|
|
generate_busnet_key
|
|
|
|
|
|
# Make sure the docker image specified by $1 is built and available for use.
|
|
buildx_image()
|
|
{
|
|
IMAGE_NAME=$1
|
|
DOCKERFILE=$2
|
|
DOCKERDIR=$3
|
|
#DOCKERARGS=""
|
|
|
|
# If --no-cache was specified, pass that on and ALSO add --pull to get the latest images.
|
|
if [[ "${BASH_ARGS}" =~ "--no-cache" ]]; then
|
|
DOCKERARGS="${DOCKERARGS} --pull --no-cache"
|
|
# If --pull was specified, pass just that on.
|
|
elif [[ "${BASH_ARGS}" =~ "--pull" ]]; then
|
|
DOCKERARGS="${DOCKERARGS} --pull"
|
|
fi
|
|
|
|
echo "Building docker image ${IMAGE_NAME} using ${DOCKERFILE} in directory ${DOCKERDIR}"
|
|
echo "Docker args: ${DOCKERARGS}"
|
|
|
|
# This uses the new docker builder. It can build multi-platform images. The default-load=true
|
|
# will load the image into the local machine so that docker image ls shows it.
|
|
docker buildx create --name busnet-builder --driver-opt=default-load=true
|
|
|
|
docker buildx build --builder busnet-builder --tag $IMAGE_NAME $DOCKERARGS --platform $CONFIG_DOCKER_BUILD_PLATFORM --file $DOCKERFILE $DOCKERDIR
|
|
}
|
|
|
|
|
|
# Execute Ansible inside the specified container. In order for this to work, the container image
|
|
# must have Ansible and required Ansible modules already installed.
|
|
# $1 playbook to execute
|
|
# $2 extra vars to pass to Ansible in --extra-vars
|
|
#
|
|
# Set the VARIABLE $DOCKER_OPTIONS with any custom options you want, and we'll pass this to the docker
|
|
# program verbatim.
|
|
ansible_playbook()
|
|
{
|
|
ANSIBLE_IMAGE_NAME="ansible-busnet"
|
|
PLAYBOOK=$1
|
|
EXTRA_VARS=$2
|
|
echo "Running Ansible playbook ${PLAYBOOK} in a container using ansible image ${ANSIBLE_IMAGE_NAME} ..."
|
|
|
|
docker inspect $ANSIBLE_IMAGE_NAME &>/dev/null
|
|
if [ $? != 0 ]; then
|
|
if [ "${ANSIBLE_IMAGE_NAME}" == "ansible-busnet" ]; then
|
|
echo "You need to build the ansible docker image first with --ansible-build"
|
|
exit 1
|
|
else
|
|
echo "I just attempted to run the container $ANSIBLE_IMAGE_NAME, but I could not because it doesn't exist on your system."
|
|
exit 1
|
|
fi;
|
|
fi
|
|
|
|
# SSH remote user
|
|
read -e -p "Enter username for remote SSH: " ansible_user
|
|
|
|
# SSH key file
|
|
ansible_ssh_private_key_file=${CONFIG_ANSIBLE_KEY_DIR_INSIDE}/${CONFIG_ANSIBLE_KEY_NAME}
|
|
|
|
EXTRA_VARS="${EXTRA_VARS} ansible_user=${ansible_user} ansible_ssh_private_key_file=${ansible_ssh_private_key_file}"
|
|
|
|
echo "EXTRA VARS (if any): ${EXTRA_VARS}"
|
|
echo
|
|
docker run \
|
|
--rm \
|
|
-it \
|
|
--network host \
|
|
$CONFIG_DOCKER_ENV \
|
|
$CONFIG_DOCKER_MOUNTS \
|
|
--name ansible-busnet-runner \
|
|
$DOCKER_OPTIONS \
|
|
$ANSIBLE_IMAGE_NAME \
|
|
ansible-playbook $PLAYBOOK --extra-vars "${EXTRA_VARS}"
|
|
}
|
|
|
|
|
|
# Regular 'ole docker run, non-interactively.
|
|
#
|
|
# $1 docker image name to run
|
|
# $2 name of the container
|
|
# $3 command to run. Defaults to sleep infinity (what's the point in that)
|
|
# $4 optional workdir
|
|
#
|
|
# Set the variable DOCKER_OPTIONS with any custom options you want, and we'll pass this to the docker
|
|
# program verbatim.
|
|
#
|
|
docker_run()
|
|
{
|
|
IMAGE_NAME=$1
|
|
CONTAINER_NAME=$2
|
|
|
|
if [[ -z "$3" ]]; then
|
|
COMMAND="sleep infinity"
|
|
else
|
|
COMMAND=$3
|
|
fi
|
|
|
|
if [[ -z "$4" ]]; then
|
|
WORKDIR=""
|
|
else
|
|
WORKDIR="-w ${4}"
|
|
fi
|
|
|
|
docker inspect $IMAGE_NAME &>/dev/null
|
|
if [ $? != 0 ]; then
|
|
if [ "${IMAGE_NAME}" == "ansible-builder" ]; then
|
|
echo "You need to build the ansible docker image first with --ansible-build"
|
|
exit 1
|
|
else
|
|
echo "I just attempted to run the container $IMAGE_NAME, but I could not because it doesn't exist on your system. You may need to build it first with build.sh"
|
|
exit 1
|
|
fi;
|
|
fi
|
|
|
|
# Stop it if it's already running.
|
|
docker_stop $CONTAINER_NAME
|
|
|
|
docker run --rm --network host ${WORKDIR} \
|
|
$CONFIG_DOCKER_MOUNTS \
|
|
$CONFIG_DOCKER_ENV \
|
|
--name $CONTAINER_NAME \
|
|
$DOCKER_OPTIONS \
|
|
$IMAGE_NAME \
|
|
$COMMAND
|
|
}
|
|
|
|
|
|
# Run a container in interactive mode. When you exit, the container exists and is removed automatically.
|
|
#
|
|
# $1 docker image name to run
|
|
# $2 name of the container
|
|
# $3 command to run. Defaults to sleep infinity (what's the point in that)
|
|
# $4 optional workdir
|
|
#
|
|
# Set the variable DOCKER_OPTIONS with any custom options you want, and we'll pass this to the docker
|
|
# program verbatim.
|
|
#
|
|
docker_run_it()
|
|
{
|
|
IMAGE_NAME=$1
|
|
CONTAINER_NAME=$2
|
|
if [[ -z "$3" ]]; then
|
|
COMMAND="sleep infinity"
|
|
else
|
|
COMMAND=$3
|
|
fi
|
|
|
|
if [[ -z "$4" ]]; then
|
|
WORKDIR=""
|
|
else
|
|
WORKDIR="-w ${4}"
|
|
fi
|
|
|
|
docker inspect $IMAGE_NAME &>/dev/null
|
|
if [ $? != 0 ]; then
|
|
if [ "${IMAGE_NAME}" == "ansible-builder" ]; then
|
|
echo "You need to build the ansible docker image first with --ansible-build"
|
|
exit 1
|
|
else
|
|
echo "I just attempted to run the container $IMAGE_NAME, but I could not because it doesn't exist on your system. You may need to build it first with build.sh"
|
|
exit 1
|
|
fi;
|
|
fi
|
|
|
|
echo "COmmand: ${COMMAND}"
|
|
|
|
# Stop it if it's already running.
|
|
docker_stop $CONTAINER_NAME
|
|
|
|
docker run --rm -it --network host ${WORKDIR} \
|
|
$CONFIG_DOCKER_MOUNTS \
|
|
$CONFIG_DOCKER_ENV \
|
|
--name $CONTAINER_NAME \
|
|
$DOCKER_OPTIONS \
|
|
$IMAGE_NAME \
|
|
$COMMAND
|
|
}
|
|
|
|
|
|
# Same as docker_run_it() but do not check if the image exists. This works only if the image is
|
|
# publicly available or in a repo that we have access to. Docker will just fetch the image automatically,
|
|
# whereas docker_run_it() will throw an error if it doesn't exst locally. Ugh.
|
|
# $1 docker image name to run
|
|
# $2 name of the container
|
|
# $3 command to run. Defaults to sleep infinity (what's the point in that)
|
|
# $4 optional workdir
|
|
#
|
|
# Set the variable DOCKER_OPTIONS with any custom options you want, and we'll pass this to the docker
|
|
# program verbatim.
|
|
#
|
|
docker_run_it_nocheck()
|
|
{
|
|
IMAGE_NAME=$1
|
|
CONTAINER_NAME=$2
|
|
if [[ -z "$3" ]]; then
|
|
COMMAND="sleep infinity"
|
|
else
|
|
COMMAND=$3
|
|
fi
|
|
|
|
if [[ -z "$4" ]]; then
|
|
WORKDIR=""
|
|
else
|
|
WORKDIR="-w ${4}"
|
|
fi
|
|
|
|
# Stop it if it's already running.
|
|
docker_stop $CONTAINER_NAME
|
|
|
|
docker run --rm -it --network host ${WORKDIR} \
|
|
$CONFIG_DOCKER_MOUNTS \
|
|
$CONFIG_DOCKER_ENV \
|
|
--name $CONTAINER_NAME \
|
|
$DOCKER_OPTIONS \
|
|
$IMAGE_NAME \
|
|
$COMMAND
|
|
}
|
|
|
|
|
|
# Run and detach a container with the command "sleep infinity". We'll then connect to this container
|
|
# with Ansible and do some tasks on it, then save its state.
|
|
# $1 docker image name to run
|
|
# $2 name of the container
|
|
# $3 command to run. Defaults to sleep infinity
|
|
#
|
|
# Set the variable DOCKER_OPTIONS with any custom options you want, and we'll pass this to the docker
|
|
# program verbatim.
|
|
#
|
|
# Set the variable DOCKER_FORCE_NEW=1 to always start a new container each time. The default is to re-use
|
|
# already running containers.
|
|
#
|
|
docker_run_detach()
|
|
{
|
|
IMAGE_NAME=$1
|
|
CONTAINER_NAME=$2
|
|
if [[ -z "$3" ]]; then
|
|
COMMAND="sleep infinity"
|
|
else
|
|
COMMAND=$3
|
|
fi
|
|
|
|
docker inspect $IMAGE_NAME &>/dev/null
|
|
if [ $? != 0 ]; then
|
|
if [ "${IMAGE_NAME}" == "ansible-builder" ]; then
|
|
echo "You need to build the ansible docker image first with --ansible-build"
|
|
exit 1
|
|
else
|
|
echo "I just attempted to run the image $IMAGE_NAME, but I could not because it doesn't exist on your system."
|
|
exit 1
|
|
fi;
|
|
fi
|
|
|
|
# Always create a new container if this flag is set.
|
|
# This stops any previously running containers. If none are running, then move on.
|
|
if [ "${DOCKER_FORCE_NEW}" == "1" ]; then
|
|
docker_stop $CONTAINER_NAME
|
|
fi
|
|
|
|
# Run the image in a container if it's not already running.
|
|
if [ $( docker ps | grep $CONTAINER_NAME | wc -l ) == 0 ]; then
|
|
echo "Running docker image ${IMAGE_NAME} in container ${CONTAINER_NAME} ..."
|
|
docker run \
|
|
--rm \
|
|
--detach \
|
|
--network host \
|
|
$CONFIG_DOCKER_MOUNTS \
|
|
$CONFIG_DOCKER_ENV \
|
|
--name $CONTAINER_NAME \
|
|
$DOCKER_OPTIONS \
|
|
$IMAGE_NAME \
|
|
$COMMAND
|
|
else
|
|
echo "Docker image ${IMAGE_NAME} already running in container ${CONTAINER_NAME}."
|
|
fi
|
|
}
|
|
|
|
|
|
# Same as docker_run_detach() but do not check if the image exists. This works only if the image is
|
|
# publicly available or in a repo that we have access to. Docker will just fetch the image automatically,
|
|
# whereas docker_run_detach() will throw an error if it doesn't exst locally. Ugh.
|
|
# $1 docker image name to run
|
|
# $2 name of the container
|
|
# $3 command to run. Defaults to sleep infinity
|
|
#
|
|
# Set the variable DOCKER_OPTIONS with any custom options you want, and we'll pass this to the docker
|
|
# program verbatim.
|
|
#
|
|
# Set the variable DOCKER_FORCE_NEW=1 to always start a new container each time. The default is to re-use
|
|
# already running containers.
|
|
#
|
|
docker_run_detach_nocheck()
|
|
{
|
|
IMAGE_NAME=$1
|
|
CONTAINER_NAME=$2
|
|
if [[ -z "$3" ]]; then
|
|
COMMAND="sleep infinity"
|
|
else
|
|
COMMAND=$3
|
|
fi
|
|
|
|
# Always create a new container if this flag is set.
|
|
# This stops any previously running containers. If none are running, then move on.
|
|
if [ "${DOCKER_FORCE_NEW}" == "1" ]; then
|
|
docker_stop $CONTAINER_NAME
|
|
fi
|
|
|
|
# Run the image in a container if it's not already running.
|
|
if [ $( docker ps | grep $CONTAINER_NAME | wc -l ) == 0 ]; then
|
|
echo "Running docker image ${IMAGE_NAME} in container ${CONTAINER_NAME} ..."
|
|
docker run \
|
|
--rm \
|
|
--detach \
|
|
--network host \
|
|
$CONFIG_DOCKER_MOUNTS \
|
|
$CONFIG_DOCKER_ENV \
|
|
--name $CONTAINER_NAME \
|
|
$DOCKER_OPTIONS \
|
|
$IMAGE_NAME \
|
|
$COMMAND
|
|
else
|
|
echo "Docker image ${IMAGE_NAME} already running in container ${CONTAINER_NAME}."
|
|
fi
|
|
}
|
|
|
|
|
|
# Stop a docker container
|
|
docker_stop()
|
|
{
|
|
CONTAINER_NAME=$1
|
|
if [ $(docker container ls | grep $CONTAINER_NAME | wc -l) -ge 1 ]; then
|
|
echo "Stopping docker container ${CONTAINER_NAME}"
|
|
docker stop $CONTAINER_NAME
|
|
fi
|
|
} |