Skip to content

Instantly share code, notes, and snippets.

@mountkin
Last active August 29, 2015 14:26
Show Gist options
  • Save mountkin/0bcf21f258e177140fe9 to your computer and use it in GitHub Desktop.
Save mountkin/0bcf21f258e177140fe9 to your computer and use it in GitHub Desktop.
#!/bin/sh
set -e
trap 'echo -ne "\e[0m"' EXIT
export PATH=$PATH:/usr/local/bin
if ps h -p $$ -o args=''|cut -f1 -d' '|grep -q bash; then
set -o pipefail
elif [ -x /bin/bash ]; then
exec /bin/bash $0
fi
DOCKER_CMD=
DOCKER_VERSION_OK=false
UPGRADE_DOCKER=false
UPGRADE_CSPHERE=false
HAS_DOCKER=true
DOCKER_REPO_URL=https://get.docker.com
DEFAULT_DATA_DIR="/data/csphere"
CONTROLLER_PORT=${CONTROLLER_PORT:-1016}
CSPHERE_VERSION=${CSPHERE_VERSION:-0.12.3}
CSPHERE_IMAGE=${CSPHERE_IMAGE:-"http://csphere-image.stor.sinaapp.com/csphere-${CSPHERE_VERSION}.tar.gz"}
set -e
url='https://get.docker.com/'
command_exists() {
command -v "$@" > /dev/null 2>&1
}
echo_docker_as_nonroot() {
if command_exists docker && [ -e /var/run/docker.sock ]; then
(
set -x
$sh_c 'docker version'
) || true
fi
your_user=your-user
[ "$user" != 'root' ] && your_user="$user"
# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output
cat <<-EOF
If you would like to use Docker as a non-root user, you should now consider
adding your user to the "docker" group with something like:
sudo usermod -aG docker $your_user
Remember that you will have to log out and back in for this to take effect!
EOF
}
install_docker() {
case "$(uname -m)" in
*64)
;;
*)
cat >&2 <<-'EOF'
Error: you are not using a 64bit platform.
Docker currently only supports 64bit platforms.
EOF
exit 1
;;
esac
user="$(id -un 2>/dev/null || true)"
sh_c='sh -c'
if [ "$user" != 'root' ]; then
if command_exists sudo; then
sh_c='sudo -E sh -c'
elif command_exists su; then
sh_c='su -c'
else
cat >&2 <<-'EOF'
Error: this installer needs the ability to run commands as root.
We are unable to find either "sudo" or "su" available to make this happen.
EOF
exit 1
fi
fi
curl=''
if command_exists curl; then
curl='curl -sSL'
elif command_exists wget; then
curl='wget -qO-'
elif command_exists busybox && busybox --list-modules | grep -q wget; then
curl='busybox wget -qO-'
fi
# check to see which repo they are trying to install from
repo='main'
if [ "https://test.docker.com/" = "$url" ]; then
repo='testing'
elif [ "https://experimental.docker.com/" = "$url" ]; then
repo='experimental'
fi
# perform some very rudimentary platform detection
lsb_dist=''
dist_version=''
if command_exists lsb_release; then
lsb_dist="$(lsb_release -si)"
dist_version="$(lsb_release --codename | cut -f2)"
fi
if [ -z "$lsb_dist" ] && [ -r /etc/lsb-release ]; then
lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")"
dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
fi
if [ -z "$lsb_dist" ] && [ -r /etc/debian_version ]; then
lsb_dist='debian'
dist_version="$(cat /etc/debian_version | sed 's/\/.*//' | sed 's/\..*//')"
case "$dist_version" in
8)
dist_version="jessie"
;;
7)
dist_version="wheezy"
;;
esac
fi
if [ -z "$lsb_dist" ] && [ -r /etc/fedora-release ]; then
lsb_dist='fedora'
dist_version="$(rpm -qa \*-release | cut -d"-" -f3 | head -n1)"
fi
if [ -z "$lsb_dist" ]; then
if [ -r /etc/centos-release ] || [ -r /etc/redhat-release ]; then
lsb_dist='centos'
dist_version="$(rpm -qa \*-release | cut -d"-" -f3 | head -n1)"
fi
fi
if [ -z "$lsb_dist" ] && [ -r /etc/os-release ]; then
lsb_dist="$(. /etc/os-release && echo "$ID")"
dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
fi
lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"
case "$lsb_dist" in
amzn)
(
set -x
$sh_c 'sleep 3; yum -y -q install docker'
)
echo_docker_as_nonroot
return 0
;;
'opensuse project'|opensuse|'suse linux'|sled)
(
set -x
$sh_c 'sleep 3; zypper -n install docker'
)
echo_docker_as_nonroot
return 0
;;
ubuntu|debian)
export DEBIAN_FRONTEND=noninteractive
did_apt_get_update=
apt_get_update() {
if [ -z "$did_apt_get_update" ]; then
( set -x; $sh_c 'sleep 3; apt-get update' )
did_apt_get_update=1
fi
}
# aufs is preferred over devicemapper; try to ensure the driver is available.
if ! grep -q aufs /proc/filesystems && ! $sh_c 'modprobe aufs'; then
if uname -r | grep -q -- '-generic' && dpkg -l 'linux-image-*-generic' | grep -q '^ii' 2>/dev/null; then
kern_extras="linux-image-extra-$(uname -r) linux-image-extra-virtual"
apt_get_update
( set -x; $sh_c 'sleep 3; apt-get install -y -q '"$kern_extras" ) || true
if ! grep -q aufs /proc/filesystems && ! $sh_c 'modprobe aufs'; then
echo >&2 'Warning: tried to install '"$kern_extras"' (for AUFS)'
echo >&2 ' but we still have no AUFS. Docker may not work. Proceeding anyways!'
( set -x; sleep 10 )
fi
else
echo >&2 'Warning: current kernel is not supported by the linux-image-extra-virtual'
echo >&2 ' package. We have no AUFS support. Consider installing the packages'
echo >&2 ' linux-image-virtual kernel and linux-image-extra-virtual for AUFS support.'
( set -x; sleep 10 )
fi
fi
# install apparmor utils if they're missing and apparmor is enabled in the kernel
# otherwise Docker will fail to start
if [ "$(cat /sys/module/apparmor/parameters/enabled 2>/dev/null)" = 'Y' ]; then
if command -v apparmor_parser >/dev/null 2>&1; then
echo 'apparmor is enabled in the kernel and apparmor utils were already installed'
else
echo 'apparmor is enabled in the kernel, but apparmor_parser missing'
apt_get_update
( set -x; $sh_c 'sleep 3; apt-get install -y -q apparmor' )
fi
fi
if [ ! -e /usr/lib/apt/methods/https ]; then
apt_get_update
( set -x; $sh_c 'sleep 3; apt-get install -y -q apt-transport-https ca-certificates' )
fi
if [ -z "$curl" ]; then
apt_get_update
( set -x; $sh_c 'sleep 3; apt-get install -y -q curl ca-certificates' )
curl='curl -sSL'
fi
(
set -x
$sh_c "apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D"
$sh_c "mkdir -p /etc/apt/sources.list.d"
$sh_c "echo deb https://apt.dockerproject.org/repo ${lsb_dist}-${dist_version} ${repo} > /etc/apt/sources.list.d/docker.list"
$sh_c 'sleep 3; apt-get update; apt-get install -y -q docker-engine'
)
echo_docker_as_nonroot
return 0
;;
fedora|centos)
cat >/etc/yum.repos.d/docker-${repo}.repo <<-EOF
[docker-${repo}-repo]
name=Docker ${repo} Repository
baseurl=https://yum.dockerproject.org/repo/${repo}/${lsb_dist}/${dist_version}
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
if [ "$lsb_dist" = "fedora" ] && [ "$dist_version" -ge "22" ]; then
(
set -x
$sh_c 'sleep 3; dnf -y -q install docker-engine'
)
else
(
set -x
$sh_c 'sleep 3; yum -y -q install docker-engine'
)
fi
echo_docker_as_nonroot
return 0
;;
gentoo)
if [ "$url" = "https://test.docker.com/" ]; then
# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-'EOF'", spaces are kept in the output
cat >&2 <<-'EOF'
You appear to be trying to install the latest nightly build in Gentoo.'
The portage tree should contain the latest stable release of Docker, but'
if you want something more recent, you can always use the live ebuild'
provided in the "docker" overlay available via layman. For more'
instructions, please see the following URL:'
https://github.com/tianon/docker-overlay#using-this-overlay'
After adding the "docker" overlay, you should be able to:'
emerge -av =app-emulation/docker-9999'
EOF
exit 1
fi
(
set -x
$sh_c 'sleep 3; emerge app-emulation/docker'
)
return 0
;;
esac
# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-'EOF'", spaces are kept in the output
cat >&2 <<-'EOF'
Either your platform is not easily detectable, is not supported by this
installer script (yet - PRs welcome! [hack/install.sh]), or does not yet have
a package for Docker. Please visit the following URL for more detailed
installation instructions:
https://docs.docker.com/en/latest/installation/
EOF
exit 1
}
num_cmp(){
if [ $# -lt 3 ];then
return 1
fi
local res=$(echo "$1 $3"|awk "{ res = \$1 $2 \$2; print res;}")
if [ $res -eq 1 ];then
return 0
else
return 1
fi
}
get_bool_choice() {
local choice
declare -l choice
while true; do
read -p "$1 [(y/yes)/(n/no)]:" choice
case "$choice" in
y|yes)
echo y
return 0
;;
n|no)
echo n
return 0
;;
esac
done
}
get_str_param() {
local str
local prompt="$1${2:+ [${2}]}: "
read -p "$prompt" str
echo $str
}
get_docker_cmd() {
if command_exists docker ; then
DOCKER_CMD=docker
elif command_exists lxc-docker; then
DOCKER_CMD=lxc-docker
else
echo "Docker not installed"
HAS_DOCKER=false
fi
}
wait_for_docker() {
echo "Waiting for docker daemon startup..."
for i in $(seq 1 120); do
if docker info >/dev/null; then
return 0
else
sleep 1
fi
done
echo "Docker daemon isn't running."
echo "Please start the Docker daemon and run this script again."
exit 1
}
check_docker_version() {
local ask_upgrade=false
local must_upgrade=false
local ver=$($DOCKER_CMD version|grep 'Server version'|cut -d ' ' -f 3|awk -F '.' '{print $1"."$2}')
if num_cmp $ver "<" 1.6; then
echo "The version of Docker is not supported."
echo "To use cSphere you must upgrade Docker to 1.6 or above."
ask_upgrade=true
must_upgrade=true
fi
if $ask_upgrade; then
echo -ne "\e[32m"
local choice=$(get_bool_choice "Do you want to upgrade your docker?")
echo -ne "\e[0m"
if [ $choice = y ]; then
UPGRADE_DOCKER=true
elif $must_upgrade; then
echo "Can't install cSphere without a supported version of Docker."
exit 1
fi
fi
}
progress_bar() {
local exitval_file=/tmp/csphere-install.$(head -n 100 /dev/urandom|tr -dc 'a-z0-9A-Z'|head -c 10)
(set -e; eval "$1"; echo $? > "$exitval_file") &
while [[ ! -e $exitval_file ]]; do
sleep 1
echo -en "."
done
echo
local exit_val=$(cat $exitval_file)
rm $exitval_file
if [ "$exit_val" != "0" ]; then
echo $2
exit $exit_val
fi
}
prepare_csphere() {
if [ "$ROLE" = "agent" -a -z "$AUTH_KEY" ]; then
echo
echo -ne "\e[31m"
echo "An auth token is required to secure the network communication between "
echo "agents and controller."
echo "If you're installing agent, you must ensure that the token here is the same"
echo "as what you had provided when installing the controller."
echo -ne "\e[0m"
echo
echo -ne "\e[32m"
while [ -z "$AUTH_KEY" ]; do
AUTH_KEY=$(get_str_param "Please input the auth token")
done
echo -ne "\e[0m"
fi
DATA_DIR=${DATA_DIR:-$DEFAULT_DATA_DIR}
[ -d $DATA_DIR ] || mkdir -p $DATA_DIR
if command_exists chcon; then
chcon -Rt svirt_sandbox_file_t $DATA_DIR >/dev/null 2>&1 || true
fi
if docker images|grep "^csphere/csphere"|grep -w -q "$CSPHERE_VERSION"; then
echo "cSphere Docker image existed "
CSPHERE_IMAGE=csphere/csphere:$CSPHERE_VERSION
return 0
fi
if echo $CSPHERE_IMAGE|grep -q http; then
local image_file=/tmp/csphere-image.$(head -n 100 /dev/urandom|tr -dc 'a-z0-9A-Z'|head -c 10).tar.gz
echo -n "Downloading cSphere Docker image "
progress_bar "$curl $CSPHERE_IMAGE >$image_file" "Failed to download cSphere Docker image."
docker load -i $image_file
CSPHERE_IMAGE=csphere/csphere:$CSPHERE_VERSION
else
docker pull $CSPHERE_IMAGE
fi
}
install_csphere_controller() {
prepare_csphere
/sbin/iptables -I INPUT -p tcp --dport $CONTROLLER_PORT -j ACCEPT > /dev/null 2>&1 || true
docker stop -t 600 csphere-controller 2>/dev/null || true
docker rm csphere-controller 2>/dev/null || true
docker run -d --restart=always --name=csphere-controller \
-v $DATA_DIR:/data:rw \
-p $CONTROLLER_PORT:80 \
-e ROLE=controller \
-e AUTH_KEY=$AUTH_KEY \
-l CSPHERE_ROLE=controller \
$CSPHERE_IMAGE
}
install_csphere_agent() {
prepare_csphere
if [ -z "$CONTROLLER_IP" ]; then
while true; do
echo -ne "\e[32m"
CONTROLLER_IP=$(get_str_param "Please input the IP address of the controller")
echo -ne "\e[0m"
[ -n "$CONTROLLER_IP" ] && break
done
fi
docker rm -f csphere-agent 2>/dev/null || true
docker run -d --restart=always --name=csphere-agent -e ROLE=agent \
-e CONTROLLER_ADDR=$CONTROLLER_IP:$CONTROLLER_PORT \
-e AUTH_KEY=$AUTH_KEY \
-v $DATA_DIR:/data:rw \
-v /proc:/rootfs/proc:ro \
-v /sys:/rootfs/sys:ro \
-v /etc:/rootfs/etc:rw \
-v /var/run/docker.sock:/var/run/docker.sock \
-l CSPHERE_ROLE=agent \
--net=host $CSPHERE_IMAGE
}
start_docker() {
if docker info >/dev/null 2>&1; then
return
fi
if [ -f /etc/init.d/apparmor ]; then
service apparmor reload || true
fi
# try every possible start methods
initctl start docker || systemctl start docker || service docker start
}
main() {
get_docker_cmd
if $HAS_DOCKER; then
start_docker
wait_for_docker
check_docker_version
if $UPGRADE_DOCKER; then
echo "Your docker daemon and all your running containers will be restarted."
if [ $(get_bool_choice "Continue?") = n ]; then
echo "Aborted"
exit 1
fi
fi
fi
if ! $HAS_DOCKER || $UPGRADE_DOCKER; then
install_docker
start_docker
wait_for_docker
fi
echo "============= install cSphere ==========="
echo "cSphere has 2 components: controller and agent."
echo -e "\e[33mThe controller should be installed before the agent.\e[0m"
if [ "$ROLE" != "controller" -a "$ROLE" != "agent" ]; then
declare -l ROLE
while true; do
echo -ne "\e[32m"
ROLE=$(get_str_param "Please input the role that you want to install")
echo -ne "\e[0m"
[ "$ROLE" = "controller" -o "$ROLE" = "agent" ] && break
done
fi
if [ "$ROLE" = "controller" ]; then
install_csphere_controller
else
install_csphere_agent
fi
}
main
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment