Skip to content

Instantly share code, notes, and snippets.

@mbentley
Last active August 29, 2015 14:13
Show Gist options
  • Save mbentley/280721b0c515fce746d2 to your computer and use it in GitHub Desktop.
Save mbentley/280721b0c515fce746d2 to your computer and use it in GitHub Desktop.
#!/bin/bash
set -e
set_variables() {
# define the full path to the docker binary
DOCKER_BINARY="/usr/bin/docker"
# define the full path to the 'zombie_dir_cleanup.py' script (see https://gist.github.com/mbentley/af9845a509b0166562b1)
VOLUME_CLEANUP_SCRIPT="/usr/local/bin/zombie_dir_cleanup.py"
}
docker_group_check() {
### check to see if the user is either root or in the 'docker' group to see whether or not to use sudo
if [ "$EUID" -eq 0 ] || [ $(groups | grep docker >/dev/null 2>&1; echo $?) -eq 0 ]
then
DOCKER_CMD="${DOCKER_BINARY}"
else
DOCKER_CMD="sudo ${DOCKER_BINARY}"
fi
}
sudo_cache() {
### check to see if user is running root; if not, cache sudo credentials
if [ "$EUID" -ne 0 ]
then
### check to see if credentials are already cached
if [ $(sudo -nv 2> /dev/null; echo $?) -eq 1 ]
then
echo "Running 'sudo true' to cache credentials"
sudo true > /dev/null
fi
fi
}
compatibility_checks() {
sudo_cache
### check to make sure the docker daemon is running
if [[ $(${DOCKER_CMD} info >/dev/null 2>&1;echo $?) -eq 1 ]]
then
echo "error: docker daemon not running or insufficient privileges (do you have proper sudo access?)"
exit 1
fi
### check for 'apt-get' binary
if [[ $(which apt-get > /dev/null; echo $?) -eq 1 ]]
then
echo "error: this script is designed to be used on systems that use APT"
exit 1
fi
### check for 'docker' binary
if [ ! -f ${DOCKER_BINARY} ]
then
echo "error: docker binary (${DOCKER_BINARY}) is not present"
exit 1
fi
}
release_version() {
### get the 'release' version install from dpkg
dpkg -l "lxc-docker-*" | grep "^ii" | awk '{print $2}' | awk -F '-' '{print $3}'
}
docker_version() {
### return the docker client version from the current binary
${DOCKER_CMD} version 2> /dev/null | grep --color=never 'Client version' | awk -F ':' '{ print $2 }' | tr -d ' '
}
docker_commit() {
### return the git commit id from the current binary
${DOCKER_CMD} version 2> /dev/null | grep --color=never 'Git commit (client)' | awk -F ':' '{ print $2 }' | tr -d ' '
}
stop_docker_service() {
### stop the docker daemon
echo -n "Stopping docker ($(docker_version) - $(docker_commit)) daemon..."
sudo /etc/init.d/docker stop >/dev/null 2>&1 && echo "done"
}
start_docker_service() {
### start the docker daemon
echo -n "Starting docker ($(docker_version) - $(docker_commit)) daemon..."
sudo /etc/init.d/docker start >/dev/null 2>&1 && echo "done"
}
stop_containers() {
### get list of running containers
CONTAINERS_RUNNING=$(${DOCKER_CMD} ps -q)
### stop running containers if there are any
if [ -z "${CONTAINERS_RUNNING}" ]
then
echo "No running docker containers to stop"
else
echo "Stopping running docker containers:"
${DOCKER_CMD} stop ${CONTAINERS_RUNNING}
fi
}
start_containers() {
### start previously running containers if there were any using list when they were stopped
if [ -z "${CONTAINERS_RUNNING}" ]
then
echo "No previously running docker containers to start"
else
echo "Starting previously running docker containers:"
${DOCKER_CMD} start ${CONTAINERS_RUNNING}
fi
}
cleanup_containers() {
### get list of containers that are in an 'exited' status
REMOVABLE_CONTAINERS=$(${DOCKER_CMD} ps -f status=exited -q -a)
### if removablecontainers are in the list; remove them
if [ -z "${REMOVABLE_CONTAINERS}" ]
then
echo "No stopped docker containers to remove"
else
echo "Removing stopped docker containers:"
${DOCKER_CMD} rm ${REMOVABLE_CONTAINERS}
fi
}
cleanup_images() {
### get list of untagged images and remove them
if [ $(${DOCKER_CMD} images | grep "^<none>" >/dev/null 2>&1; echo $?) -eq 0 ]
then
echo "Removing untagged docker images:"
${DOCKER_CMD} rmi $(${DOCKER_CMD} images | grep "^<none>" | awk '{print $3}')
else
echo "No untagged docker images to remove"
fi
}
cleanup_volumes() {
### check for 'zombie_dir_cleanup.py' script
if [ ! -f ${VOLUME_CLEANUP_SCRIPT} ]
then
echo "error: zombie_dir_cleanup.py script (${VOLUME_CLEANUP_SCRIPT}) is not present"
echo " see https://gist.github.com/mbentley/af9845a509b0166562b1"
exit 1
else
sudo_cache
### run python script to cleanup volumes that have been orphaned
sudo ${VOLUME_CLEANUP_SCRIPT}
fi
}
backup_binary() {
### check to see if binary is a 'test', 'master', or 'release' version and backup accordingly
if [ $(${DOCKER_CMD} version 2> /dev/null | grep 'Client version' | grep '\-dev' >/dev/null 2>&1; echo $?) -eq 0 ]
then
echo -n "Backing up 'docker' to 'docker.master'..."; sudo cp ${DOCKER_BINARY} ${DOCKER_BINARY}.master && echo "done"
else
if [ "$(release_version)" = "$(docker_version)" ]
then
echo -n "Backing up 'docker' to 'docker.release'...";sudo cp ${DOCKER_BINARY} ${DOCKER_BINARY}.release && echo "done"
else
echo -n "Backing up 'docker' to 'docker.test'...";sudo cp ${DOCKER_BINARY} ${DOCKER_BINARY}.test && echo "done"
fi
fi
}
cleanup_test_backup() {
### remove the 'test' binary backup if it exists
if [ -f ${DOCKER_BINARY}.test ]
then
echo -n "Removing 'docker.test' backup..."; sudo rm ${DOCKER_BINARY}.test && echo "done"
else
echo "Nothing to cleanup"
fi
}
cleanup_master_backup() {
### remove the 'master' binary backup if it exists
if [ -f ${DOCKER_BINARY}.master ]
then
echo -n "Removing 'docker.master' backup..."; sudo rm ${DOCKER_BINARY}.master && echo "done"
else
echo "Nothing to cleanup"
fi
}
cleanup_release_backup() {
### remove the 'release' binary backup if it exists
if [ -f ${DOCKER_BINARY}.release ]
then
echo -n "Removing 'docker.release' backup..."; sudo rm ${DOCKER_BINARY}.release && echo "done"
else
echo "Nothing to cleanup"
fi
}
install_test() {
sudo_cache
stop_containers
stop_docker_service
backup_binary
### check to see if a backup of 'test' exists; if it does, install it. otherwise, download a new copy
if [ -f ${DOCKER_BINARY}.test ]
then
echo -n "Backup of 'test' available; installing backup file..."; sudo cp ${DOCKER_BINARY}.test ${DOCKER_BINARY} && echo "done"
else
echo "No backup of 'test' available; downloading and installing 'test' docker binary"
sudo wget -q --show-progress -O ${DOCKER_BINARY} https://test.docker.com/builds/Linux/x86_64/docker-latest && sudo chmod 755 ${DOCKER_BINARY}
backup_binary
fi
start_docker_service
start_containers
}
upgrade_test() {
sudo_cache
stop_containers
stop_docker_service
cleanup_test_backup
echo "Downloading and installing new 'test' docker binary"
sudo wget -q --show-progress -O ${DOCKER_BINARY} https://test.docker.com/builds/Linux/x86_64/docker-latest && sudo chmod 755 ${DOCKER_BINARY}
backup_binary
start_docker_service
start_containers
}
install_master() {
sudo_cache
stop_containers
stop_docker_service
backup_binary
### check to see if a backup of 'master' exists; if it does, install it. otherwise, download a new copy
if [ -f ${DOCKER_BINARY}.master ]
then
echo -n "Backup of 'master' available; installing backup file..."; sudo cp ${DOCKER_BINARY}.master ${DOCKER_BINARY} && echo "done"
else
echo "No backup of 'master' available; downloading and installing 'master' docker binary"
sudo wget -q --show-progress -O ${DOCKER_BINARY} https://master.dockerproject.com/linux/amd64/docker && sudo chmod 755 ${DOCKER_BINARY}
backup_binary
fi
start_docker_service
start_containers
}
upgrade_master() {
sudo_cache
stop_containers
stop_docker_service
cleanup_master_backup
echo "Downloading and installing new 'master' docker binary"
sudo wget -q --show-progress -O ${DOCKER_BINARY} https://master.dockerproject.com/linux/amd64/docker && sudo chmod 755 ${DOCKER_BINARY}
backup_binary
start_docker_service
start_containers
}
install_release() {
sudo_cache
stop_containers
backup_binary
### check to see if a backup of 'release' exists; if it does, install it. otherwise, re-install the currently installed debian package
if [ -f ${DOCKER_BINARY}.release ]
then
stop_docker_service
echo -n "Backup of 'release' available; installing backup file..."; sudo cp ${DOCKER_BINARY}.release ${DOCKER_BINARY} && echo "done"
start_docker_service
else
echo "No backup of 'release' available; installing 'release' binary via apt"
sudo apt-get install --reinstall -q -y $(dpkg -l "lxc-docker-*" | grep "^ii" | awk '{print $2}')
backup_binary
fi
start_containers
}
upgrade_release() {
sudo_cache
stop_containers
cleanup_release_backup
echo "Current docker version: $(docker_version) - $(docker_commit)"
echo "Installing new 'release' binary via apt"
sudo apt-get install -qq --reinstall -y lxc-docker
echo "New docker version: $(docker_version) - $(docker_commit)"
backup_binary
start_containers
}
main(){
SCRIPT=$(basename $0)
UTIL=${1:-help}
CMD=${2:-}
set_variables
docker_group_check
case ${UTIL}:${CMD} in
cleanup:containers)
compatibility_checks
cleanup_containers
;;
cleanup:images)
compatibility_checks
cleanup_images
;;
cleanup:volumes)
compatibility_checks
cleanup_volumes
;;
cleanup:all)
compatibility_checks
cleanup_containers
cleanup_images
cleanup_volumes
;;
cleanup:*)
echo "Usage: ${SCRIPT} cleanup {all|containers|images|volumes}"
exit 1
;;
install:test)
compatibility_checks
install_test
;;
install:master)
compatibility_checks
install_master
;;
install:release)
compatibility_checks
install_release
;;
install:*)
echo "Usage: ${SCRIPT} install {test|master|release}"
exit 1
;;
upgrade:test)
compatibility_checks
upgrade_test
;;
upgrade:master)
compatibility_checks
upgrade_master
;;
upgrade:release)
compatibility_checks
upgrade_release
;;
upgrade:*)
echo "Usage: ${SCRIPT} upgrade {test|master|release}"
exit 1
;;
*:*)
echo "Usage: ${SCRIPT} cleanup {all|containers|images|volumes}"
echo "Usage: ${SCRIPT} install {test|master|release}"
echo "Usage: ${SCRIPT} upgrade {test|master|release}"
exit 1
;;
esac
echo "done."
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment